Reputation: 73
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.
Upvotes: 5
Views: 4855
Reputation: 1
Hibernate uses a property "clazz_" to determine subclasses.
Example:
select
animal0_.animal_id as animal_i1_0_,...,
case
when animal0_1_.animal_id is not null then 1
when animal0_2_.animal_id is not null then 2
when animal0_.animal_id is not null then 0
end as clazz_
from animal animal0_
left outer join dog animal0_1_ on animal0_.animal_id=animal0_1_.animal_id
left outer join cat animal0_2_ on animal0_.animal_id=animal0_2_.animal_id
You should specify SQL with "0 AS clazz_"
@Query(value = "SELECT *, 0 AS clazz_ FROM animal", nativeQuery = true)
List<Animal> findAllAnimal();
Upvotes: 0
Reputation: 431
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:
@Query(value = "SELECT * FROM animal", nativeQuery = true)
List<Resource> findAllAnimal();
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/
Upvotes: 0
Reputation: 23105
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:
Upvotes: 3