Realsolve Logo
Articles
 

Hibernate Pitfall: Why Relationships Should Be Lazy

Last update, January 17, 2005

Overview

If you do not use lazy associations, it is remarkably easy to unwittingly fall into the trap of executing many unnecessary SQL statements in your Hibernate applications. This pitfall shows how easily this problem can manifest itself, and how it can be overcome.

Problem

Suppose we have a class Manufacturer with a many-to-one relationship with Contact. In other words, one contact can be related to many manufacturers (think, for example, of our contact as a reseller for one or more manufacturers, but with exclusive right to sell for the manufacturer).

Lets suppose we want to list the name of the manufacturers, but for the purposes of this query we do not care about any of the manufacturer's contact information. We simply run the query

Query query = session.createQuery( "from Manufacturer manufacturer");
List list = query.list();
//do something with the list of Manufacturer instances

The query that Hibernate generates is to get the data that we want is

select ... various field names ... from MANUFACTURER

We're okay so far. The problem is what comes next. Without us asking it to do anything, we get another set of SQL statements, one for each of the five referenced contacts in the CONTACTS table.

select ... various field names ... from CONTACT where CONTACT.id=?
select ... various field names ... from CONTACT where CONTACT.id=?
select ... various field names ... from CONTACT where CONTACT.id=?
select ... various field names ... from CONTACT where CONTACT.id=?
select ... various field names ... from CONTACT where CONTACT.id=?

This is the N+1 selects problem

Solution

The solution is to make the Contact class lazy, simply by enabling the lazy attribute in the Contact's hbm.xml mapping definition file.

<class name="example.domain.Contact" table="CONTACT" lazy = 
"true">
...
</class>

A similar effect can be achieved by using the proxy = "example.domain.Contact" attribute.

The result is for the same code we executed earlier, only the first select statement is executed. Of course, we are still vulnerable to the N+1 selects problem if, at some point in the future, someone actually decides they need to use Contact information. We show how to deal with this pitfall in Avoiding The N+1 Selects

More Hibernate Tips and Pitfalls

This is a working document. If there are any errors, or if you disagree with anything which I have said, or have any suggestions for improvements please email me at philzoio@realsolve.co.uk.