stdcall
stdcall

Reputation: 28900

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);

Upvotes: 6

Views: 3841

Answers (4)

mirijason
mirijason

Reputation: 11

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 :)

Upvotes: 1

zAlbee
zAlbee

Reputation: 1189

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.

Upvotes: 1

jk2
jk2

Reputation: 79

According to the Hibernate Reference this is working!

Multiple classes can appear, resulting in a cartesian product or "cross" join.

from Formula, Parameter

(See 14.2)

Hibernate Reference

You could also search in both Tables seperately and then check which one isn't null?

Upvotes: -1

JB Nizet
JB Nizet

Reputation: 691785

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.

Upvotes: 2

Related Questions