Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate Polymorphic HQL SELECT statement

I'm Using Hibernate annotation to persist my classes. Currently I'm using the following strategy to map the classes

I have an abstract class which is the Parent class, and I have two sub-classes which inherit from it Mother, Father.

I mapped it like that:

@MappedSuperclass
public abstract class Parent {

private int age;
private String name;
...
}

And the two other classes are declared like this:

@Entity
public Class Father extends Parent {

private boolean haveMustash;
...
}

So basically the scenario is "Table per Class".

Now I want to create an Hibernate HQL statement that will update the age of a parent, regardless of it's kind (mother,father). the parent will be looked up using the name column, which is unique in both of the tables. but I don't know just looking at the name if it is Mother or Father. How can I create a HQL statement that will look in both of the tables, and return the right entity to update ?

I thought about something like this: (but I don't have an idea if it is even possible)

Parent parent = hibernateTemplate.find("from Mother,Father where name="
        + name);
like image 287
stdcall Avatar asked Nov 30 '11 08:11

stdcall


3 Answers

from Parent p where p.name = :name

(not tested).

Note that if it works, it will lead to two queries, since both entities have nothing in common, except they inherit some mapped attributes from a superclass. You don't have entity inheritance here, and don't implement the table per class strategy. You would if Parent was annotated with @Entity rather than @MappedSuperClass, and if you defined an inheritance strategyusing @Inheritance.

like image 186
JB Nizet Avatar answered Oct 09 '22 15:10

JB Nizet


JB Nizet's answer is correct. Use @Entity to map Parent, instead of @MappedSuperclass. This allows you to run Hibernate queries and updates on Parent, (the latter only lets you run it on Father and Mother). You can keep your table per class with the @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) annotation.

from Mother,Father won't work since that implicitly joins the tables. What you want is a union. Using @Entity, Hibernate will do this for you automatically.

like image 37
zAlbee Avatar answered Oct 09 '22 17:10

zAlbee


I'm 7 years late but anyway.

I'm actually having the same kind of issue. I have a parent class that is @MappedSuperClass and two children classes that are @Entity. I do not wish to make the parent class @Entity but still would like to benefit from polymorphic queries. Apparently, according to https://www.baeldung.com/hibernate-inheritance, you can use :

from insert.full.package.name.here.Parent p where p.name = :name

by using the full class name with its package, although I haven't tried this yet. I may edit this post after I have tried this ;) Hopefully, this might help someone facing this issue again.

Edit : So indeed, this works fine for me :)

like image 22
mirijason Avatar answered Oct 09 '22 15:10

mirijason