File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Object Relational Mapping and the fly likes hibernate left join fetch question Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Databases » Object Relational Mapping
Bookmark "hibernate left join fetch question" Watch "hibernate left join fetch question" New topic
Author

hibernate left join fetch question

Joe Gliniecki
Greenhorn

Joined: Oct 25, 2007
Posts: 18
I am doing some volunteer work for the local school district. We are using Hibernate for O/R mapping, and for general searches, we don't need much of the object graph returned. So I set fetch="join" in the XML for the parts of the object graph we want returned. However, we saw that Hibernate was doing n + 1 selects. Turns out it was for this reason.

So I removed all fetch="join" entries from the XML and now use "left join fetch" in the HQL - problem solved.

But now if I want to drill down and get one entity and its object graph, I need to use"left join fetch" in the HQL and do a query rather than just loading it by its ID. The query returns a list of one object and I have to do a to grab the first object to return the entity from the DAO (which seems ugly and I'd rather avoid).

Is there any way that I can just load the object using its ID and get the object graph? The only way I can see to get the object graph is to specify in the XML (which results in the n + 1 problem for queries) or to specify "left join fetch" in the HQL. I'd rather not do a full blown query since I already have the object's primary key id.

Thanks
Benjamin Winterberg
Ranch Hand

Joined: Sep 19, 2007
Posts: 36
Joe Gliniecki wrote:So I removed all fetch="join" entries from the XML and now use "left join fetch" in the HQL - problem solved.

If you use session#get(), Hibernate builds the query considering the fetch="join" mapping. This mapping is only ignored when you build your own HQL or criteria queries. So, no need to remove the fetch="join".

If you get the N+1 select problem witch fetch="join" while using session#get() then please post your mapping config.


Hibernate DAOs with Spring | Separation of Concerns | Eclipse Code Templates | more...
Javid Jamae
Author
Ranch Hand

Joined: May 14, 2008
Posts: 198
Read this. You'll need to put lazy="false" to define the association as non-lazy, then you can can decide whether to use fetch="select" (the default) or fetch="join". If I'm not mistaken, these settings are ignored for HQL queries, so removing them shouldn't have affected the N+1 issue on your HQL queries the way you concluded.


Author: JBoss in Action, javidjamae.com, @javidjamae on Twitter
Joe Gliniecki
Greenhorn

Joined: Oct 25, 2007
Posts: 18
I looked into this deeper and here is what I make out:

We were using session.load() in our DAO, but we keep our session in the DAO. Thus our business classes access the domain objects in detached mode. Thus we needed the hibernate XML to have the classes specified as lazy="false" since load() is lazy by default.

So when I had a many-to-one relationship with fetch="join" and the "one" side of the relationship had its class set to lazy="false", I had the n+1 problem. If I made the class lazy, then the n+1 problem went away, but then loading that class would not be lazy.

So I used session.get() which in non-lazy by default, and removed all lazy="false" from the classes and just have fetch="join" for the relationships and everything works fine: In one query I get the whole object graph when using get() with the object id, and in one query I get a subset of the object graph when using left join fetch in the HQL.

Hope this helps someone, but not sure why I had the n+1 problem when the class was set to lazy="false".
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: hibernate left join fetch question
 
Similar Threads
Suppressing association retrievals
Alternating between Eager and Lazy Fetching
Hibernate Hell
Want to avoid multiple SELECT when using "new" in HQL
how to set fetch type at runtime ? + Hibernate