-->
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.  [ 4 posts ] 
Author Message
 Post subject: Criteria API Problem
PostPosted: Mon Jun 19, 2006 9:43 am 
Newbie

Joined: Mon Jun 19, 2006 9:11 am
Posts: 3
i thought that it would be possible to define which nested collections or nested persistent classes are loaded and how they are loaded at runtime by using the Criteria api?

But this seems not to be possible:


the DAO-layer:

Code:
   public Concert loadConcert(long id, String[] fetchGroups) {
      Criteria c = this.getSession().createCriteria(Concert.class)
         .add(Restrictions.idEq(id));
      if (fetchGroups != null) {
         for (int i = 0; i < fetchGroups.length; ++i) {

      c = c.setFetchMode(fetchGroups[i], FetchMode.SELECT);
         }
      }
      
      return (Concert) c.uniqueResult();
   }



the buisness-layer

Code:
   public Concert getConcert(long id) {

      Concert conc = this.concertDao.load(id, new String[] { "bands", "location" });
     //session is closed, conc is detached
    return conc;
   }


the mapping file

Code:
<hibernate-mapping>
   <class name="bandzine.domain.Concert" table="CONCERT">
      <id name="id" column="ID">
         <generator class="native"/>
      </id>
      <property name="name" column="NAME"/>
      
      <property name="fromDate" column="FROM_DATE"/>
      <property name="toDate" column="TO_DATE"/>      
      <many-to-one name="location" column="LOCATION_ID" class="bandzine.domain.Location"/>
   

      <set name="bands" table="CONCERT_BAND" lazy="false">
         <key column="CONCERT_ID"/>
         <many-to-many class="bandzine.domain.Band" column="BAND_ID"/>
      </set>
   </class>
   
   <class name="bandzine.domain.Location" table="LOCATION">
      <id name="id" column="ID">
         <generator class="native"/>
      </id>

      <property name="name" column="NAME"/>

      
      <set name="concerts" inverse="true" lazy="false">
         <key column="LOCATION_ID"/>
         <one-to-many class="bandzine.domain.Concert"/>
      </set>      
   </class>   
   
   <class name="bandzine.domain.Band" table="BAND">
      <id name="id" column="ID">
         <generator class="native"/>
      </id>
      <property name="name" column="NAME"/>

      
      <set name="concerts" inverse="true" table="CONCERT_BAND" lazy="false">
         <key column="BAND_ID"/>
         <many-to-many class="bandzine.domain.Concert" column="CONCERT_ID"/>
      </set>   
   </class>


c.setFetchMode(fetchGroups[i], FetchMode.SELECT); does not fetch the nested Objects. So how can i define which nested objects are initialized before detaching at runtime. it only seems to be possible to define it in the xml-mapping by setting the lazy property to lazy="false". But i don't want all nested objects to be loaded every time. i want to be able to create an individual fetch-plan at runtime! ORM like jdo support this, so why not hibernate??


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 20, 2006 1:04 am 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
FetchMode.SELECT is essentially lazy: if you want to eagerly load, use FetchMode.JOIN. The javadocs for FetchMode are very strange: FetchMode.SELECT says that it's eager, but the docs for FetchMode.LAZY say:
Code:
public static final FetchMode LAZY

    Deprecated. use FetchMode.SELECT

    Fetch lazily. Equivalent to outer-join="false".
I'm not terribly au fait with laziness, but that certainly tells me that SELECT is not what you want.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 20, 2006 6:32 am 
Newbie

Joined: Mon Jun 19, 2006 9:11 am
Posts: 3
Thank that's exactly what i wanted to know. But the documentations also tell that using FetchMode.JOIN is imperformant when more than one nested Collection is loaded because of the cartesian product.

So the only way to force Hibernate to fetch nested Collections at Runtime via SELECTs is to execute something like
Code:
Hibernate.initialize(object.getCollection())
, am i right?

thx


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 20, 2006 5:48 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
That's certainly a good way to do it: that guarantees that any associated entities that are referenced more than once have to be loaded only once. FetchMode.JOIN will load every object, every time it's needed.

The alternative is to switch to OpenSessionInView, so that you can lazily load objects whenever you need to, and not worry about eagerly loading things. See http://www.hibernate.org/43.html

_________________
Code tags are your friend. Know them and use them.


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