-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: join fetch behavior: do I understand this?
PostPosted: Mon Nov 12, 2007 12:24 pm 
Newbie

Joined: Fri Nov 09, 2007 6:57 pm
Posts: 3
I have a situation where I'm trying to pre-load a child collection so I won't have the N+1 select problem later.

I started by following the guidelines in this Blog post: http://ayende.com/Blog/archive/2007/03/ ... rnate.aspx

Basically, the idea is to use the "left join fetch" syntax in my query to load the child collection. When I issue a query like this:
list = session.CreateQuery("from Blog blog left join fetch blog.Posts post" ).List();
instead of getting one item back for each Blog row, I get duplicate Blogs, one for each Post so the number of items in the list is equal to the total number of Posts, not the total number of Blogs.

If I change the mapping file to fetch="join" and lazy="false" then do a query with just "from Blog" I get the same behavior.

Changing the mapping file to fetch="subselect" gives me one entry in the list for each Blog as I expected with the original query.

Should the join fetch bring multiple copies of the parent object?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 13, 2007 10:58 am 
Regular
Regular

Joined: Thu Nov 23, 2006 10:29 am
Posts: 106
Location: Belgium
Hi,

This is expected behaviour.

Most of the time, I use a
Code:
criteria.SetResultTransformer(new NHibernate.Transform.DistinctRootEntityResultTransformer());

to limit the doubles.

I'm not sure how you can do this in HQL.

_________________
Please rate this post if it helped.

X.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 13, 2007 11:01 am 
Newbie

Joined: Fri Nov 09, 2007 6:57 pm
Posts: 3
Interesting. You'd think NHibernate should be smart enough to not do that.

Thanks for the relpy. At least now I can quit looking for where I configured it incorrectly...


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 14, 2007 9:06 am 
Senior
Senior

Joined: Thu Feb 09, 2006 1:30 pm
Posts: 172
We use the DISTINCT keyword in our HQL when this situation occurs. You should get the result you want, although the SQL probably isn't as ideal as it should be. Note that the fetch will not cause a loss of data since every child entity will result in a distinct row from the database.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 14, 2007 10:26 am 
Newbie

Joined: Fri Nov 09, 2007 6:57 pm
Posts: 3
Thanks.

Actually, I tried the distinct keyword and it didn't seem to help.
Maybe I didn't get the syntax exactly right:

IList<IBaseOrder> orders = theSession.CreateQuery("select distinct bo from BaseOrder bo left join fetch bo.LineItems li left join fetch li.Product").List<IBaseOrder>();

Maybe it got confused because I was trying to load an attribute in the child object at the same time.

The distinct shouldn't make any difference in the SQL result set returned in this case since it should join all the line items anyway.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 14, 2007 12:19 pm 
Senior
Senior

Joined: Thu Feb 09, 2006 1:30 pm
Posts: 172
jrandeck wrote:
The distinct shouldn't make any difference in the SQL result set returned in this case since it should join all the line items anyway.


The result set is the same, as I stated. I say it is less than ideal because the keyword impacts the query plan in a negative way. Since the results are the same the change to the query plan only serves to hinder performance. It may not be noticeable in your case, but it is a difference.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 14, 2007 3:44 pm 
Expert
Expert

Joined: Tue Aug 23, 2005 5:52 am
Posts: 335
The issue is that NHibernate will return duplicates based on their relationship with the joined items, however the duplicates are not actually duplicate objects, just duplicate references the same object.

You can unique-ify the list by creating a HashedSet (or similar) and adding each item in the returned list to the set.

Cheers,

Symon.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.