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?