-->
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: Avoid loading a big collection when adding elements to it
PostPosted: Mon Jan 15, 2007 1:48 pm 
Newbie

Joined: Mon Jan 15, 2007 1:18 pm
Posts: 8
Hi,

I use Hibernate 3.2.1ga. I have a relationship one-to-many from Account to Transaction, where the number of transactions per account could be very big. I have mapped this as a Set as follows:
<set name="transactions" table="transaction" lazy="extra">
<key>
... primary key here ...
</key>
<one-to-many class="class name"/>
</set>

In some cases I need to add a new Transaction to the Account, but I'm not interested in loading the full collection, as I'm not interested in any of the existing Transactions, to avoid this I decided to use lazy="extra" in the mapping, as you can see.

The problem is that, even when the collection will not be loaded when adding then Transaction to the collection, Hibernate is loading the collection at flush() time. Notice that when I used lazy="true" it would load the collection as soon as I added the Transaction to the collection.

Is there any way to avoid Hibernate loading the collection at all in this case? In fact the flush() happens at the end of my transaction, so I don't see why anything needs to be loaded at this point (notice that I use Spring 2.0.2 for transaction support).
I have tried adding the Transaction directly through the repository too, (i.e. by doing a saveUpdate() instead of using the collection), but with the same results.

Any help is welcome. In general I'm wondering up to what point is wise to have tables with lots of records mapped as collections, as the performance hit can be quite bad when reading it. Any general ideas/suggestions on this subject as well? Maybe there is some generic pattern out there that be can used in these cases? or maybe Hibernate supports them in some better way?

The following are my Hibernate settings:
Code:
  <bean id="hibernateProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="properties">
      <props>
        <prop key="hibernate.dialect">org.hibernate.dialect.InformixDialect</prop>
        <prop key="hibernate.jdbc.batch_size">100</prop>
        <prop key="hibernate.show_sql">false</prop>
        <prop key="hibernate.auto_import">true</prop>
        <prop key="hibernate.bytecode.use_reflection_optimizer">true</prop>
        <prop key="hibernate.query.substitutions">true=1,false=0</prop>
        <prop key="hibernate.use_outer_join">true</prop>
        <prop key="hibernate.max_fetch_depth">3</prop>
        <prop key="hibernate.connection.release_mode">auto</prop>
        <prop key="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</prop>
        <prop key="hibernate.jdbc.use_scrollable_resultset">false</prop>
        <prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.SingletonEhCacheProvider</prop>
      </props>
    </property>
  </bean>

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 15, 2007 2:00 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
1) don't use <set>, use <bag> (set requires a return value true/false for add's, bag's don't)

2) don't map the collection if you don't need it ;)

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 15, 2007 9:29 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 7:19 pm
Posts: 2364
Location: Brisbane, Australia
You could make the relation bi-directional with inverse="true" and only update on the many-to-one side of the relation, eg, don't need to put it into the set. Just update the Transaction side with the Account parent only.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 15, 2007 11:37 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
David, that would break in-memory referential integrity for the unit of work (or any detached instances that are left over after the unit of work). Don't recommend that :) The mantra is that any bidirectional association needs to be updated on both sides, and that inverse mappings don't change that.

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


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 15, 2007 11:38 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
The solution is like Max outlined: Use a bag. Of course you should not map this collection in the first place. The whole point of a collection mapping is the convenience of iteration instead of manual querying for data. You are never going to iterate through a very large collection. Use a query instead when you need that information.

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


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 16, 2007 5:48 am 
Newbie

Joined: Mon Jan 15, 2007 1:18 pm
Posts: 8
Thanks all,

I agree that not mapping this collection looks like the solution that makes more sense. Particularly taking into account that all I'll ever want is a view on its contents, in which case I better access it through the Repository with the right criteria when required.

It is useful knowing about the bag too, I won't use it in this particular case but it could come in handy for other situations.

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 29, 2007 11:44 am 
Newbie

Joined: Tue Apr 25, 2006 12:04 pm
Posts: 10
Location: Buenos Aires
read the documentation about collecions mapping with the property lazy="extra"


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.