-->
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.  [ 2 posts ] 
Author Message
 Post subject: How to prevent large collection fetching?
PostPosted: Wed Jul 23, 2008 7:06 am 
Newbie

Joined: Mon Jan 16, 2006 8:41 am
Posts: 6
Hello,

I am handling two type of objects. The first is a Visit, which keeps track of a user visit to a web site, the second is the user itself.

So we have:

User.getVisits() ==> Collection of visits.

As soon as the user logs in to the web page, i create a new visit, as follow:

...
Visit visit = new Visit(new Date());
user.getVisits().add(visit);
session.save(visit);
...

When a user starts to have a large number of visits (roughly 10000), the call to "user.getVisits().add(visit)" takes some time to execute (few seconds, with an index on Visit.ID and Visit.userFK).

I have tried to set the association from User to Visit to lazy="true", a little better but not immediate

I have tried to set the association from User to Visit to lazy="extra", a little better but no change with "lazy=true"

By looking at the (SQL) logs produced by Hibernate, i can see that hibernate is ALWAYS fetching the whole visit object, not only the ID (which would be much faster i think so)

Is there any way of doing this or optimizing this?

My Mapping files:

<hibernate-mapping default-cascade="none">
<class name="com.cvsft.model.user.UserLoginImpl" table="USER_LOGIN" dynamic-insert="false" dynamic-update="false" >
<id name="id" type="java.lang.Long" unsaved-value="null">
<column name="ID" sql-type="BIGINT"/>
<generator class="native">
</generator>
</id>
<property name="username" type="java.lang.String">
<column name="USERNAME" not-null="true" unique="false" sql-type="VARCHAR(255)"/>
</property>
<property name="password" type="java.lang.String">
<column name="PASSWORD" not-null="true" unique="false" sql-type="VARCHAR(255)"/>
</property>
<property name="passwordHint" type="java.lang.String">
<column name="PASSWORD_HINT" not-null="false" unique="false" sql-type="VARCHAR(255)"/>
</property>
<property name="lastSuccessFullLogin" type="java.util.Date">
<column name="LAST_SUCCESS_FULL_LOGIN" not-null="false" unique="false" sql-type="DATETIME"/>
</property>
<property name="enabled" type="boolean">
<column name="ENABLED" not-null="true" unique="false" sql-type="TINYINT"/>
</property>
<property name="noFailedLogins" type="int">
<column name="NO_FAILED_LOGINS" not-null="true" unique="false" sql-type="INTEGER"/>
</property>
<property name="rootGroupShortName" type="java.lang.String">
<column name="ROOT_GROUP_SHORT_NAME" not-null="true" unique="false" sql-type="VARCHAR(255)"/>
</property>
<property name="multiSessionEnabled" type="boolean">
<column name="MULTI_SESSION_ENABLED" not-null="true" unique="false" sql-type="TINYINT"/>
</property>
<property name="rootGroupAdmin" type="boolean">
<column name="ROOT_GROUP_ADMIN" not-null="true" unique="false" sql-type="TINYINT"/>
</property>
<property name="portalStyle" type="java.lang.String">
<column name="PORTAL_STYLE" not-null="false" unique="false" sql-type="VARCHAR(255)"/>
</property>
<property name="expirationDate" type="java.util.Date">
<column name="EXPIRATION_DATE" not-null="false" unique="false" sql-type="DATETIME"/>
</property>
<property name="keywords" type="java.lang.String">
<column name="KEYWORDS" not-null="false" unique="false" sql-type="VARCHAR(2048)"/>
</property>
<property name="comments" type="java.lang.String">
<column name="COMMENTS" not-null="false" unique="false" sql-type="VARCHAR(2048)"/>
</property>
<property name="modificationUser" type="java.lang.String">
<column name="MODIFICATION_USER" not-null="true" unique="false" sql-type="VARCHAR(255)"/>
</property>
<property name="creationUser" type="java.lang.String">
<column name="CREATION_USER" not-null="true" unique="false" sql-type="VARCHAR(255)"/>
</property>
<property name="lastModificationDate" type="java.util.Date">
<column name="LAST_MODIFICATION_DATE" not-null="true" unique="false" sql-type="DATETIME"/>
</property>
<property name="creationDate" type="java.util.Date">
<column name="CREATION_DATE" not-null="true" unique="false" sql-type="DATETIME"/>
</property>
<set name="visits" order-by="USER_LOGIN_FK" lazy="true" fetch="select" inverse="false" cascade="delete,delete-orphan">
<cache usage="read-write" />
<key >
<column name="USER_LOGIN_FK" sql-type="BIGINT"/>
</key>
<one-to-many class="com.cvsft.model.user.VisitImpl"/>
</set>
<many-to-one name="user" class="com.cvsft.model.user.UserImpl" lazy="proxy" fetch="select">
<column name="USER_FK" not-null="true" sql-type="BIGINT"/>
</many-to-one>
<set name="userAuthHosts" order-by="USER_LOGIN_FK" lazy="false" fetch="select" inverse="true" cascade="save-update,merge,delete,delete-orphan">
<cache usage="read-write" />
<key >
<column name="USER_LOGIN_FK" sql-type="BIGINT"/>
</key>
<one-to-many class="com.cvsft.model.user.UserAuthHostImpl"/>
</set>
</class>
</hibernate-mapping>

<hibernate-mapping default-cascade="none">
<class name="com.cvsft.model.user.VisitImpl" table="VISIT" dynamic-insert="false" dynamic-update="false" >
<id name="id" type="java.lang.Long" unsaved-value="null">
<column name="ID" sql-type="BIGINT"/>
<generator class="native">
</generator>
</id>
<property name="startDate" type="java.util.Date">
<column name="START_DATE" not-null="false" unique="false" sql-type="DATETIME"/>
</property>
<property name="endDate" type="java.util.Date">
<column name="END_DATE" not-null="false" unique="false" sql-type="DATETIME"/>
</property>
<property name="ipAddress" type="java.lang.String">
<column name="IP_ADDRESS" not-null="false" unique="false" sql-type="VARCHAR(255)"/>
</property>
<property name="startUrl" type="java.lang.String">
<column name="START_URL" not-null="false" unique="false" sql-type="VARCHAR(255)"/>
</property>
<set name="activities" order-by="VISIT_FK" lazy="true" fetch="select" inverse="true" cascade="save-update,merge,delete,delete-orphan">
<cache usage="read-write" />
<key >
<column name="VISIT_FK" sql-type="BIGINT"/>
</key>
<one-to-many class="com.cvsft.model.user.ActivityImpl"/>
</set>
</class>
</hibernate-mapping>

Thanks a lot for your idea/suggestions/help!

Jean-Baptiste


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 25, 2008 3:31 am 
Expert
Expert

Joined: Tue May 13, 2008 3:42 pm
Posts: 919
Location: Toronto & Ajax Ontario www.hibernatemadeeasy.com
If the relationship is set to lazy, Hibernate should be just putting in a proxy, not the whole object. Are you accessing or looping through the associated objects by any chance, causing Hibernate to load them all?

_________________
Cameron McKenzie - Author of "Hibernate Made Easy" and "What is WebSphere?"
http://www.TheBookOnHibernate.com Check out my 'easy to follow' Hibernate & JPA Tutorials


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