-->
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.  [ 6 posts ] 
Author Message
 Post subject: Lazy Loading Question
PostPosted: Sun May 06, 2007 4:14 pm 
Newbie

Joined: Thu Feb 08, 2007 1:28 pm
Posts: 9
Let me start by saying I've read through all the documentation I could find, and searched google extensively, and read through the lazy loading section in Java Persistence with Hibernate.

I feel as though a lot of performance can be gained from lazy loading, which we don't use at all right now.

I'm using hibernate version 3. I don't remember the exact version.

Here is my hibernate mapping file:
Code:
<class name="EAAssessmentLog" table="SA_EAAssessmentLogs">
      <id name="id" column="ealogId" >
         <generator class="native"/>         
      </id>
      <property name="ea" type="string" length="50" />
      <property name="assessment" column="assessment" type="AssessmentEnum" length="20" />
      <property name="assessmentNote" />      
      <property name="finished" />      
      <!-- primary is a keyword -->
      <property name="primary" column="primaryRole" length="255" />      
      <property name="primaryNameString" length="100" />   
      <many-to-one name="triggers" class="emst.dao.command.CommandFulfillmentGroup" cascade="persist,merge,save-update" lazy="false"/>
      <many-to-one name="fulfillment" class="emst.dao.command.CommandFulfillmentGroup" cascade="persist,merge,save-update" lazy="false"/>      
      <many-to-one name="actionConsequences" class="emst.dao.command.CommandFulfillmentGroup" cascade="persist,merge,save-update" lazy="false"/>      
      <many-to-one name="inactionConsequences" class="emst.dao.command.CommandFulfillmentGroup" cascade="persist,merge,save-update" lazy="false"/>
      <many-to-one name="stoppers" class="emst.dao.command.CommandFulfillmentGroup" cascade="persist,merge,save-update" lazy="false"/>
      
      <list name="annotations" lazy="false" table="SA_EALogAnnotations" cascade="persist,save-update,merge">
         <key column="id"/>
         <list-index column="idx"/>
         <many-to-many column="commands" class="emst.dao.command.Command"/>
      </list>
      
      <list name="prompts" lazy="false" table="SA_EALogPrompts" cascade="persist,save-update,merge">
         <key column="id"/>
         <list-index column="idx"/>
         <many-to-many column="commands" class="emst.dao.command.Command"/>
      </list>
      
      <list name="reminders" lazy="false" table="SA_EALogReminders" cascade="persist,save-update,merge">
         <key column="id"/>
         <list-index column="idx"/>
         <many-to-many column="commands" class="emst.dao.command.Command"/>
      </list>
   </class>


If I remove the lazy="false" I start getting lazy instantiation errors. They look something like this:
Code:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: emst.dao.assessment.EAAssessmentLog.annotations, no session or session was closed


Here is the code I use to access it:
Code:
   public List<EAAssessmentLog> getEAAssessmentLog(List<Long> ids)
   {
      Session session = HibernateUtil.getSessionFactory().getCurrentSession();
      session.beginTransaction();

      List<EAAssessmentLog> eAAssessmentLogs = new ArrayList<EAAssessmentLog>();

      for(Long ealog:ids)
      {
         try
         {
            eAAssessmentLogs.add((EAAssessmentLog) session.get(EAAssessmentLog.class, new Long(ealog)));
         }
         catch(HibernateException e)
         {
            session.getTransaction().rollback();
            throw e;
         }
      }
      
      try
      {
         session.getTransaction().commit();
      }
      catch(HibernateException e)
      {
         session.getTransaction().rollback();
         throw e;
      }

      return eAAssessmentLogs;
   }


Now, if I don't put the session.getTransaction().commit() it will work. I was wondering if it's acceptable to just not do a session.getTransaction().commit().

I have a Manager class for all the persistent classes that retrieve the object in a similar fashion. So I don't do any lazy instantiation throughout the entire program. I feel as though there can be a good performance benefit from this, but I'm not sure how to go about making the change.

Also, sometimes an actionListener will access data in the object that i would like to lazily load. How do I go about doing that, as I don't know if or when the loading will be done, which makes it hard to keep the session open. Should I open a session in the action listener? Is that how this kind of thing is done?

Do I add data access logic to the programming logic to get this done? Since the beginning of this, I've had all the hibernate code in the manager classes I mentioned. Where I make a call to the Manager class and it opens the session, retrieves what i'm looking for, closes the session, and then returns the object. Is that a good design?


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 07, 2007 12:23 am 
Expert
Expert

Joined: Tue Jan 30, 2007 12:45 am
Posts: 283
Location: India
Hi jlafata,

When to use LAZY..

Let say you have lot of complex object modeling is there For an Example one Object has many association .But as your business doesn’t require every data in every business operation. For concrete Example

XYZ has PQR and LMN association and you have tow business call ,First one uses some data of PQR and second call uses both PQR and LMN. Not going to very detail .If you analyzed these call in first call doesn’t require to load LMN and all business call need PQR so making PQR as lazy is costly but making LMN as lazy is quite good approach , because it save data loading time for first business call.

Another area of concern is which one heavy object that include lot of field. These comes when you are using legacy system .for that several time you need not to work with ever field but business call requires operation on some of the field at that situation you could use lazy property. Might be hibernate team could elaborate more.

_________________
Dharmendra Pandey


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 07, 2007 12:47 pm 
Newbie

Joined: Thu Feb 08, 2007 1:28 pm
Posts: 9
That didn't answer my question. I understand what lazy loading does, and most places will tell you when to use it. I'm looking more for how to use it.


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 07, 2007 11:35 pm 
Expert
Expert

Joined: Tue Jan 30, 2007 12:45 am
Posts: 283
Location: India
Hi jlafata,

on class tag you could use

class name="ABC" table="abc" lazy="true"

By default Hibernate 3.1 and later version all association are lazy. You could explicitly use with

Set tag lazy="true"

with bag tag lazy="true"

with list tag lazy="true"

same as for property lazy="true"

with many-to-one lazy="true" or other.

Use XML plugin that would tell you where to use lazy. It is not that much important how to use rather than when to use.

_________________
Dharmendra Pandey


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 08, 2007 9:08 am 
Newbie

Joined: Thu Feb 08, 2007 1:28 pm
Posts: 9
I understand how to set it in the XML. I understand when it's beneficial. My question is mostly about the source code.

Right now we put all of the Hibernate code in manager classes separate from everything else. The function will go off and do it's thing, and then return an object of the type we want. The session is closed by that time. I was wondering is it good to keep the hibernate code separate, or is it common to mix it with your code?


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 08, 2007 9:36 am 
Expert
Expert

Joined: Tue Jan 30, 2007 12:45 am
Posts: 283
Location: India
Hi jlafata,

I would prefer not to use this way. Because when the session is closed ,you would not get the benefit of lazy loading. Keep your transaction in the scope within business logic, and other thing you could use like save update,etc operation by your hibernate layer. These call should be within business logic

_________________
Dharmendra Pandey


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