How to use LEFT JOIN in Hibernate Criteria

January 29th, 2009  | Tags: , ,

Criteria, in my opinion, is the most fantastic mechanism for querying ever created. Hibernate has an excellent API for Criteria and many users use it a lot, including me :). However by default, Hibernate Criteria uses INNER JOIN internally and depends on the situation, it doesn’t work as expected.

As you probably know, INNER and LEFT JOIN are quite different. Generally speaking, INNER JOIN is used when both sides of the associations exists, as long as LEFT JOIN is used when only the LEFT side of the relationship exists. Let’s look at a real example.

Supposing we have the following diagram:

As you can see above, there is a relationship One-To-Many between Person and Children. As usual, One Person can have none or more children, as well as a Children has only one Father (at least, biological).

Now, supposing we wanna a list of all People. If he/she has children, show up the list of them, otherwise, show up only the Person’s name. To do that, we could create an HQL like below:

Query query = getSession().createQuery("SELECT p FROM Person p LEFT JOIN p.listChildren children");

Note: We’ve used LEFT JOIN, but why? Because if the PERSON has no relationship (no children) the query MUST retrieve the values as well. If the query was like this:

Query query = getSession().createQuery("SELECT p FROM Person p INNER JOIN p.listChildren children");

The Person with no relationship (no children) will not be retrieved by the query. The INNER JOIN looks in both side of the relationship. It’s not good for that requirement.

Building the same query using Criteria

Supposing we’re going to create the same HQL above but using Criteria. The sintaxe could be:

Criteria criteria = getSession().createCriteria(Person.class);
criteria.addAlias("listChildren","children");
criteria.list();

Hibernate will read the code above and transform it in an HQL that uses INNER JOIN. The problem with that approach is that the Person with no Children will not be retrieved. So, how to change the default behavior from Hibernate Criteria Associations?

Using LEFT JOIN in Hibernate Criteria

Fortunatelly, there is a simple way to change the default behavior from Hibernate. Simply use the “CriteriaSpecification.LEFT_JOIN” argument. Hence, the Criteria above would be:

Criteria criteria = getSession().createCriteria(Person.class);
criteria.addAlias("listChildren","children",CriteriaSpecification.LEFT_JOIN);
criteria.list();

Conclusion

Criteria API is a powerful mechanism for querying in Hibernate. It can be used for simple and advanced queries. As you saw in this post, the Criteria API is also flexible. Try to use Criteria when you have dynamic parameters. Do not worry about SQL, HQL or anything else besides Objects :).

I hope this topic be useful. If you have any question or comment, fell free to leave your message below.

  1. Andrew Spencer
    May 29th, 2009 at 12:30
    #1

    Thanks, you saved me some headaches with this tip.

  2. billson
    February 26th, 2010 at 12:41
    #2

    yeah,finally i got this…
    using criteria to do left join.
    tks man.

TOP