-->
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.  [ 1 post ] 
Author Message
 Post subject: Eager (join) fetching with Criteria
PostPosted: Mon Mar 07, 2005 11:02 am 
Newbie

Joined: Mon Mar 07, 2005 7:25 am
Posts: 10
I'm having problems with FetchMode.JOIN in Criteria. This has to do with unrecommendable Cartesian products, but please read on...

Suppose there's a Customer object with 2 underlying collections (addresses and invoices). These collections have to be eagerly loaded at runtime when required, through the criteria mechanism. The results are detached from the session.

Now, this works:
Code:
...
Query query = session.createQuery("from Customer customer left join fetch customer.addresses left join fetch invoices where customer.lastName = ?");
query.setString(0, "Parker");
...
session.close(); // detaching
...
customer.getAddresses();
customer.getInvoices();


Hibernate appearantly does 2 subsequent selects (1 to get customers + addresses, 1 to get the invoices for each customer).

However, this does not work:
Code:
session.createCriteria(Customer.class).add(Restrictions.eq("lastName", "Parker")).setFetchMode("invoices", FetchMode.JOIN).setFetchMode("addresses",FetchMode.JOIN);
...
session.close(); // detach
...
customer.getAddresses();
customer.getInvoices();


The last part gives you a LazyLoadingException on getInvoices(), the addresses load properly. Now, this is mentioned in the code and the documentation as being a case where Hibernate refuses to do a Cartesian product (reasonable). However, is there a way to mimic the 2-fase select that occurs in HQL with Criteria? It would seem Hibernate could use the same "common sense" it uses for HQL when multiple outer joins are required...

Even stranger is the fact that if you use this HQL query:
Code:
from Customer customer left join fetch customer.addresses left join fetch customer.invoices where customer.lastName = ?

(notice it says "customer.invoices" instead of just "invoices" in the first example)
Hibernate does generate a Cartesian "double" outer join in it's first SQL call (which I thought was semi-illegal) and subsequently does that secondary SELECT as well (which is at that point redudant).

All in all, the JOIN fetching behaves quite differently in these three cases that seem to me like exactly the same thing.

Thomas Goorden

More specifics:

Hibernate version: 3.0 beta 4

Code:
   <class name="Customer"
      <id name="id" column="id" type="string" access="field">
         <generator class="uuid.hex" />
      </id>
      <timestamp name="updateTS" access="field" />
      <property name="lastName" type="string" />
      <set name="addresses" inverse="false" lazy="true" access="field" cascade="save-update">
         <key column="customerId" not-null="true" />
         <one-to-many class="Address" />
      </set>
      <set name="invoices" inverse="false" lazy="true" access="field" cascade="save-update">
         <key column="customerId" not-null="true" />
         <one-to-many class="Invoice" />
      </set>
   </class>
... (trivial implementations for Address and Invoice)


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

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.