-->
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: HQL Wierdness?
PostPosted: Sat Apr 01, 2006 7:33 am 
Expert
Expert

Joined: Tue Aug 23, 2005 5:52 am
Posts: 335
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version: NHibernate 1.0.2

I've got some strange behavior with an HQL statement and I'm not sure whether or not it's by design - hopefully someone can clarify for me.

I have a domain model where there are Parent objects and Child objects where the Parent object has a collection of children - Parent.Children.

Assuming there are 2 Parents in the DB and Parent #1 has 1 child and Parent #2 has 2 Children I would expect the following HQL query to return two Parent obects with the Children property collections populated.

Code:
SELECT p FROM Parent p LEFT JOIN FETCH p.Children



This assumption is based on the following from the documentation:

Quote:
In addition, a "fetch" join allows associations or collections of values to be initialized along with their parent objects, using a single select. This is particularly useful in the case of a collection. It effectively overrides the outer join and lazy declarations of the mapping file for associations and collections.

...Also, the associated objects are not returned directly in the query results. Instead, they may be accessed via the parent object.


What I'm getting, however, is 3 Parent objects: 1x Parent #1 and 2x Parent #2.

Have I misunderstood the documentation? Or is something else not right here?

Symon.[/quote]


Top
 Profile  
 
 Post subject:
PostPosted: Sat Apr 01, 2006 9:43 am 
Senior
Senior

Joined: Sat May 14, 2005 8:40 am
Posts: 130
I'm afraid this is by design. In the past, I also ran into this issue and it appeared to be by design. Still don't know the exact reason for it though.

I worked around this issue by creating a small utility class that filters the duplicates.

_________________
Cuyahoga


Top
 Profile  
 
 Post subject:
PostPosted: Sat Apr 01, 2006 10:15 am 
Expert
Expert

Joined: Tue Aug 23, 2005 5:52 am
Posts: 335
Seems strange that it's by design when the docs seem to be contradictory. I'll have to look into why.

Thanks for the suggestion on the filtering though.

Cheers,

Symon.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Apr 02, 2006 7:01 am 
Expert
Expert

Joined: Tue Aug 23, 2005 5:52 am
Posts: 335
OK, after reading the FAQ and doing a little digging on the forums I'm still pretty much in the dark over why there's a discrepancy between what the docs say and the actual result.

The Hibernate FAQ entry entitled "Hibernate does not return distinct results for a query with outer join fetching enabled for a collection (even if I use the distinct keyword)" says:

Quote:
Query result lists are always exactly the same size as the underlying JDBC ResultSet.


But *why*? This means that I need to know whether the query is going to perform an outer join fetch to know whether or not I need to distinctify the results. Otherwise, I might remove duplicate instances that are supposed to be in a result set, right?

I've been putting together a web service API to allow users to execute arbitrary HQL queries against my domain model. To do this I've generated proxy classes with an IsLazy property and am making all lazy objects and collections in the query result set return an unpopulated proxy marked lazy. It was my intention to allow the user to populate a selected collection property of each returned object by using the "join fetch" HQL construct, but then it skews the result set.

I suppose I could try parsing the HQL statement for "join fetch" to determine whether or not I need to distinctify the results, but this just seems like a bit of a kludge.

Why was the choice was made to make the result set match the size of the underlying DB result set? This should probably be in the docs since it directly contradicts what's currently written there.

Cheers,

Symon.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 03, 2006 4:02 am 
Senior
Senior

Joined: Thu Aug 25, 2005 3:35 am
Posts: 160
Martijn_b: Do you really need your own utility class? I had one too, but I could use: .SetResultTransformer(CriteriaUtil.DistinctRootEntity);
on my queries to let nh do it.

Maybe on straight hql you can't?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 03, 2006 5:59 am 
Senior
Senior

Joined: Sat May 14, 2005 8:40 am
Posts: 130
TheShark wrote:
Martijn_b: Do you really need your own utility class? I had one too, but I could use: .SetResultTransformer(CriteriaUtil.DistinctRootEntity);
on my queries to let nh do it.

Maybe on straight hql you can't?


Is this when using the Criteria API? I only ran into this with straight hql (via IQuery). Looks like a good solution though. Maybe something like this also exists in the IQuery interface and I just overlooked it.

_________________
Cuyahoga


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 03, 2006 6:30 am 
Senior
Senior

Joined: Thu Aug 25, 2005 3:35 am
Posts: 160
yes, this is using the criteria api

ICriteria c = s.CreateCriteria(typeof(Functie))
.SetFetchMode("RolIDs", FetchMode.Join)
.AddOrder(new NHibernate.Expression.Order("Naam", true))
.SetResultTransformer(CriteriaUtil.DistinctRootEntity);

LijstEntiteiten<Functie> functies = new LijstEntiteiten<Functie>(c.List());

I'd be interested in an iQuery method for it as well. ;-)


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.