I have an scenario as the following:
@Entity
@Table(name = "ANIMAL")
@Inheritance(strategy = InheritanceType.JOINED)
public class Animal implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "S_ANIMAL")
@SequenceGenerator(name = "S_ANIMAL", sequenceName = "S_ANIMAL", allocationSize = 1)
public int getNumero() {
return numero;
}
public void setNumero(int numero) {
this.numero = numero;
}
.
.
.
}
and as the subclass:
@Entity
@Table(name = "DOG")
public class Dog extends Animal {
private static final long serialVersionUID = -7341592543130659641L;
.
.
.
}
I have a JPA Select statement like this:
SELECT a FROM Animal a;
I'm using Hibernate 3.3.1
As I can see the framework retrieves instances of Animal
and also of Dog
using a left outer join.
Is there a way to Select only the "part" Animal
? I mean, the previous Select
will get all the Animal
s, those that are only Animal
s but not Dog
s and those that are Dog
s.
I want them all, but in the case of Dog
s I want to only retrieve the "Animal part" of them.
I found the @org.hibernate.annotations.Entity(polymorphism = PolymorphismType.EXPLICIT)
but as I could see this only works if Animal isn't an @Entity
.
Thanks a lot.
Short answer: The behaviour you describe complies with JPA standard. There is no JPA standard way to restrict the JPA provider to retrieve only the superclass.
The provider can choose query implementation logic to achieve functionality, consistency & performance. As long as it respects your entity annotations and returns the requested information in the query all is good. Think of the outer join to Dog as private implementation detail that should not concern you. The provider has coded an outer join to assist performance and consistency.
Consider:
In terms of time taken: query with animal table is only slightly faster (10s of microseconds???) than query with animal outer joined to dog, but is much faster than two separate queries (one for animal and one for dog)
Actually, there is a way to get just the superclass: you just need to use the native query from JPA. In my case, I am using JPA Repositories. Therefore, it would be something like that:
The flag nativeQuery as true allow running the native SQL on database.
If you are using Entity Manager then check this out: https://www.thoughts-on-java.org/jpa-native-queries/