-->
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.  [ 8 posts ] 
Author Message
 Post subject: pg 580: 13.2.3 Eager fetching with joins
PostPosted: Thu Mar 08, 2007 11:07 pm 
Newbie

Joined: Thu Mar 01, 2007 5:02 pm
Posts: 8
I don't want my first post about the book to be too negative so I should say that in almost every regard it has been phenomenal: easy to read, well indexed, and thorough. It's been and will continue to be and indispensable resource well worth the six copies we purchased. I guess I'm just grumpy because I spent the better part of day trying to figure out why some of my results had duplicates. As soon as I left the book and did a Google search I found the hundreds of discussions on the topic.

Anyway, here's the issue. Page 580 of Java Persistence with Hibernate states:
Code:
If you now load many Item objects, for example with createCriteria(Item.class).list(), this is how the resulting SQL statement looks:
    select i.*, b.*
    from ITEM i
        left outer join BID b on i.ITEM_ID = b.ITEM_ID

The resultset now contains many rows, with duplicate data for each Item that has many bids, and NULL fillers for all Item objects that don’t have bids. Look at the resultset in figure 13.5.

Hibernate creates three persistent Item instances, as well as four Bid instances, and links them all together in the persistence context so that you can navigate this graph and iterate through collections—even when the persistence context is closed and all objects are detached.

It's that last paragraph that I believe has led us to some confusion. I would agree that this what is written is indeed what should happen, however it doesn't appear that this is the case. In fact this contradicts the more accurate statement found in the Advanced Problems FAQ:
Code:
Hibernate does not return distinct results for a query with outer join fetching enabled for a collection (even if I use the distinct keyword)?

Query result lists are always exactly the same size as the underlying JDBC ResultSet. Try using uniqueResult() if appropriate, or simply distinctify the results yourself using, eg.

Collection results = new HashSet( session.createQuery("select p from Parent p left join fetch p.children").list() );

This filters out duplicate references, not duplicate "objects" or values. To understand why the duplicate references appear, have a look at the SQL resultset. Hibernate does not by default hide these duplicate references but mimics the SQL resultset. If you want to keep the order of elements, use a LinkedHashSet. An alternative in Hibernate 3.2 is a ResultTransformer that can filter duplicate references (in memory, of course).

Of course, I suppose it's possible to interpret the book text in such a way that these two items don't contradict each other, but I think that vast majority of people reading that section of the book would take away from that snippet of text that the List returned from the createCriteria(Item.class).list() statement would contain 3 items with the child associations properly initialized. At the very least, users should be made aware that they will have duplicate objects in their returned list so that they can apply one of the available techniques for removing those duplicates. We have 4 people on my team reading this book and to a person, they each struggled with this behavior because of the way the book text is worded.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 08, 2007 11:33 pm 
Newbie

Joined: Thu Mar 01, 2007 5:02 pm
Posts: 8
For what it's worth, the text on page 580 is reinforced by the following text on page 589:
Code:
Hibernate immediately removes all the duplicates when it marshals the resultset into persistent objects and collections—redundant information is skipped.

Again, this does not appear to be the case.

Of course, I may be a fool and have something misconfigured, however the Advanced Problems FAQ referenced above would indicate otherwise.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 09, 2007 4:29 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
1. Page 580 talks about eager join fetching _as defined in the global fetching strategy in mapping metadata_ and explains what happens behind the scenes when you navigate your graph of objects in Java code.

2. The Advanced FAQ explains what happens when you _execute a query by calling a query API and writing a query by hand_. A "query result list" is not the same as a metadata fetching strategy. These two things are conceptually connected, of course, but very different user-visible features. Page 580 does not explain queries, the section is called "Selecting a metadata fetching strategy".

3. Page 589 is also not about queries but about the metadata fetching strategy.

If you want to know why your queries return duplicate references when you use joins, look in chapter 14 "Querying with HQL", section 14.3 "Joins", and note the last item on page 651.

This is really an annoying FAQ and there seems to be now way to educate Hibernate users on OUTER JOINs. In fact, when I do training, half of the people in the room usually have no clear idea what a SQL OUTER JOIN is. So we can write FAQs as much as we want, it's not going to help.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 09, 2007 4:35 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
And yes, the Criteria API is different, so if you use that, read chapter 15, section 15.1.2 "Joins and dynamic fetching", subsection "Dynamic fetching with criteria queries". The FAQ is discussed extensively in that section.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 09, 2007 5:11 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
I've rewritten the FAQ.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 09, 2007 10:44 am 
Newbie

Joined: Thu Mar 01, 2007 5:02 pm
Posts: 8
I reread my original post an I apologize if I came off with a bad attitude. Like I said it's a fantastic book, but I had just spent a long time trying to figure out what I was doing wrong and was a little grumpy. Sorry about that and thanks for the information. That will hopefully help me get my hibernate setup straightened out.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 11, 2007 4:54 pm 
Newbie

Joined: Sun Jan 14, 2007 2:52 pm
Posts: 19
Just found this topic after spending a few hours trying to figure out why the query on page 587 was returning a load of duplicates, so you were not the only one who thought it was mis-leading! Although Christian's response is correct, when you go back and read it in that context the book is right. Suppose it serves me right for thinking I could skip chapter 14 before starting working :)


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 11, 2007 7:04 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
The last paragraph on that page even says: "Go read the next chapter!" :)

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 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.