-->
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.  [ 5 posts ] 
Author Message
 Post subject: fetch=join when navigating object graph
PostPosted: Wed Feb 01, 2006 9:00 pm 
Newbie

Joined: Tue Nov 04, 2003 2:19 pm
Posts: 5
Location: Emeryville, California
Hibernate version: 3.01

Hello,

The docs and previous posts seem to focus on Criteria queries to facilitate the fetch=join strategy. Though the reference manual suggests that simple object navigation should utilize the stategy if specified in the mapping files. I'm a bit unclear as to what that exactly means - since we cannot get a desireable result.

A 1:m B 1:m C (ugly entity diagram :-))

We've specified in the B mapping to C that fetch="join". This is sterling when we get B by id. B and all of its C's are fetched with a single SQL query.

If we ask A for the set of B's then we get the B's in a single SQL. But invariably "N" more queries are executed to get each C for each B - where N is the number of B's.

As an aside: we want to keep the fetching of the set of B's lazy when navigating from A to the B collection.

I realize we haven't provided actual mapping files yet. But as a first posted question - is what we're attempting achievable? To paraphrase the question:

Is it possible, given a reference to object A, to iterate over its collection of Bs and have that iteration trigger precisely a single SQL query where all the B's and their associated C's (via an outer join) are read from the database? That was a pedantic mouthful.

Regards,

Barry


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 01, 2006 9:11 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
Assuming that your hibernate.max_fetch_depth is set to 2 or higher, I believe that calling Hibernate.initialize on your A object will do an outer join over both B and C, resulting in the required single select (with a potentially massive result set).


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 02, 2006 1:52 pm 
Newbie

Joined: Tue Jun 14, 2005 10:27 am
Posts: 2
Thanks for the reply.

I'm happy the reply didn't say it was impossible. But we tried the suggestion and it still executed N+1 queries. Also, I was hoping for a solution that didn't include explicit hibernate involvement. We were hoping that just navigating the object tree should trigger the single sql select.


So I guess it's time to show my (trimmed down) mapping files and beg for further assistance.


In the order of A, B, C: FileFolder has Documents which has LinkSetDocuments.

<hibernate-mapping>
<class name="FileFolder" table="T_FILE_FDR">
<id name="id" column="FILE_FDR_ID" type="CharStrType" />
<set name="documents" inverse="true">
<key column="FILE_FDR_ID" />
<one-to-many class="Document" />
</set>
</class>
</hibernate-mapping>

<hibernate-mapping>
<class name="Document" table="T_DOC">
<id name="id" column="DOC_ID" type="CharStrType" />
<many-to-one name="fileFolder" class="FileFolder" column="FILE_FDR_ID" not-null="true" />
<set name="linkSets" inverse="true" fetch="join">
<key column="DOC_ID" />
<one-to-many class="LinkSetDocument" />
</set>
</class>
</hibernate-mapping>


<hibernate-mapping>
<class name="LinkSetDocument" table="T_LSET_DOC">
<id name="id" column="LSET_DOC_ID" type="CharStrType">
<generator class="HibernateKeyGenerator" />
</id>
<many-to-one name="linkSet" class="LinkSet" column="LSET_ID" not-null="true" fetch="join"/>
<many-to-one name="document" class="Document" column="DOC_ID" not-null="true" fetch="join" />
</class>
</hibernate-mapping>


Top
 Profile  
 
 Post subject: apologies for unformatted mapping files - trying again
PostPosted: Thu Feb 02, 2006 2:14 pm 
Newbie

Joined: Tue Jun 14, 2005 10:27 am
Posts: 2
Code:
<hibernate-mapping>
   <class name="FileFolder" table="T_FILE_FDR">
      <id name="id" column="FILE_FDR_ID" type="CharStrType" />
      <set name="documents" inverse="true">
         <key column="FILE_FDR_ID" />
         <one-to-many class="Document" />
      </set>
   </class>
</hibernate-mapping>

<hibernate-mapping>
   <class name="Document" table="T_DOC">
      <id name="id" column="DOC_ID" type="CharStrType" />
      <many-to-one name="fileFolder" class="FileFolder" column="FILE_FDR_ID" not-null="true" />
      <set name="linkSets" inverse="true" fetch="join">
         <key column="DOC_ID" />
         <one-to-many class="LinkSetDocument" />
      </set>
   </class>
</hibernate-mapping>


<hibernate-mapping>
   <class name="LinkSetDocument" table="T_LSET_DOC">
      <id name="id" column="LSET_DOC_ID" type="CharStrType">
         <generator class="HibernateKeyGenerator" />   
      </id>
      <many-to-one name="linkSet" class="LinkSet" column="LSET_ID" not-null="true" fetch="join"/>
      <many-to-one name="document" class="Document" column="DOC_ID" not-null="true" fetch="join" />
   </class>
</hibernate-mapping>



Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 02, 2006 5:13 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
Is the FileFolder to Document association the only one you want to be lazily-loaded? What happens if you put lazy="false" on the other associations, as well as fetch="join"?

Alternatively, if you know at query time which associations you want eagerly loaded, just write several named queries and choose between them:
Code:
<query name="FileFolderLazyLinks">
from FileFolder ff
where (your conditions here)
</query>

<query name="FileFolderEagerLinks">
from FileFolder ff
join fetch ff.Documents ds
join fetch d.LinkSets lss
join fetch lss.LinkSet ls
join fetch lss.Document d
where (your conditions here)
</query>
Etc. etc.


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