How can I write a query for Hibernate criteria for a superclass and test for a specific subclass?

How can I write a Hibernation Criteria query for a superclass and test a specific subclass? Suppose we have the following classes, all mapped to Hibernate-JPA:

@Entity @Inheritance(strategy = InheritanceType.JOINED) public class Bar { @Id @Column(name = "id") private Long id; } @Entity @PrimaryKeyJoinColumn(name="bar_id") public class Foo extends Bar { } @Entity @PrimaryKeyJoinColumn(name="bar_id") public class Goo extends Bar { } 

When writing a Criteria query like this, I would like, for performance, to use a left join with a subclass:

 getSession() .createCriteria(Bar.class) .createAlias("Foo", "foo", CriteriaSpecification.LEFT_JOIN) .add(Restrictions.isNotNull("foo.bar_id")) .list(); 

This fails because the association path "Foo" does not work explicitly, but it will illustrate what I want. Or is there another way to make this type of request? I need a request for a superclass. If I did this in SQL, it would look like this:

 select b.* from bar b left join foo f on f.bar_id = b.id where f.bar_id is not null; 

The above SQL query simply illustrates what I mean, I know that it would be easier to use a β€œnormal” connection in this particular case.

+6
source share
1 answer

It is not clear what you want to do.

First of all, since Foo inherits from Bar, finding instances of Bar automatically returns instances of Foo. Hibernate will take care of joining tables by itself.

Secondly: your SQL query is really strange. You make a left join (this means you are looking for bars that might not have an associated foo), but you also have a place where foo.bar_id is not null. This is actually an inner join and can be rewritten as

 select b.* from bar b inner join foo f on f.bar_id = b.id 

If you want to search for Foos and Foos, use Criteria with Foo as the root object:

 getSession() .createCriteria(Foo.class) .list(); 

You will get instances of Foo, but since Foo extends Bar, these instances of Foo are also instances of Bar. This is what inheritance is.

Now, if you create a Criteria instance dynamically and at some point realize that the search should return only Foo instances, you should use the implicit class property:

 Criteria c = getSession().createCriteria(Bar.class, "bar") // ... if (limitToFoos) { c.add(Restrictions.eq("bar.class", Foo.class)); } 
+7
source

Source: https://habr.com/ru/post/891871/


All Articles