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: lazyInitializationException when accessing a parent property
PostPosted: Mon Aug 04, 2008 5:37 pm 
Regular
Regular

Joined: Tue Feb 19, 2008 6:05 pm
Posts: 82
I am getting a lazyInitializationException whenever I access a child objects' parentObject property defined using a
many-to-one relationship in the child mapping file (see childObj.hbm.xml). I access my child object using a DAO method (see the DAO below) which uses the session.get(child.class,childId) method to return my childObj object. I am able to access the parent object and its properties using this child object only the first time!. The second time I try to use the same method it throws the lazyInitializationException
for no reason I can understand!

Interestingly, if I include a simple print statement in the DAO method which prints the parents property before returning
the child object, the lazyInitializationException does not occur any more also allowing access to the parent object properties ???


I do not want to use a eager fetching strategy as this DAO and the method that returns the child object is a generic method
used by other classes and might rarely need to access the parent object property.

A print statement in the action class that calls the DAO shows the session is available although the error message:
SEVERE: could not initialize proxy - no Session

Also, I have no idea why the print statement in the DAO is able to run that extra query to fetch the parent
while accessing the parent property whereas without the print statement directly accessing the parent objects
properties results in a lazyInitializationException.

My mapping file property and may-to-one relationships:
childObj.hbm.xml
Code:
<property name="recordDeletedBy" column="record_deleted_by"/>
   <property name="recordDeletedDate" column="record_deleted_date_time"/>
      
   <many-to-one name="parent1"        column="parent1_id"          class="Parent1" unique="true" />
   <many-to-one name="parent2"  column="parent2_id"    class="Parent2" unique="true"   />


SomeAction.java
Code:
public ActionForward populateDetails(ActionMapping mapping,
         ActionForm form, HttpServletRequest request,
         HttpServletResponse response) throws Exception
{
      SomeActionForm rForm = (SomeActionForm) form;
      if (rForm.getSelectedItem() != null) {
         RsAwardDAO aDao = new RsAwardDAOImpl();
         

         ChildObj child = childDao.findChild(someChildId);

         /* This statement shows that the session is available as this statement prints as true*/
         Session session = ConnectDAO.getSessionInstance();
         System.out.println("Is session open: " + session.isOpen());
   
         
         /* here below child.getParent1().getParentName() throws the lazyInitializationExpcetion
         from the second time onwards if there is no print statement in the SomeDAOImpl.java */
         try {
            if (!child.getParent1() != null) {
               rForm.setRsTypeName(child.getParent1().getParentName());
            }
            
         } catch (LazyInitializationException lie) {
            lie.printStackTrace();
         }
      }

      return mapping.findForward("success");
}


and finally the DAO that returns the child object
SomeDAOImpl.java
Code:
public ChildObj findChild(Long childId)
{
      try
      {
         Session session = ConnectDAO.getSessionInstance();
         ChildObj child = (ChildObj) session.get(ChildObj.class, childId);
         

         /* If I include a simple print statement to access the parent object property here,
            not only does it print properly, I do not have lazyInitializationException problems accessing
            in the calling class outside this DAO method */

         if (child.getParent1().getParentName() != null)
            System.out.println("Parent name: "
                  + child.getParent1().getParentName()
                  + " in the SomeDAOImpl findChild() method");
               
         return child;
      } catch (HibernateException ex)
      {
         System.out.println("ERROR:  Datbase error occured");
         ex.printStackTrace();
      }
      return null;
}      



Aug 4, 2008 4:15:45 PM org.hibernate.LazyInitializationException <init>
SEVERE: could not initialize proxy - no Session
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150)
at database.Parent1$$EnhancerByCGLIB$$21b8203f.getParent1(<generated>)
at actions.rs.someAction.populateDetails(someAction.java:371)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:269)
at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:170)
at org.apache.struts.chain.commands.servlet.ExecuteAction.execute(ExecuteAction.java:58)
at org.apache.struts.chain.commands.AbstractExecuteAction.execute(AbstractExecuteAction.java:67)
at org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51)
at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190)
at org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:304)
at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190)
at org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:462)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:118)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Thread.java:619)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 05, 2008 2:16 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
I think the problem is caused by the ConnectDAO.getSessionInstance() method. Does it return the same session when you call it from the findChild() method as when you call it from the populateDetails() method? What happens to the session that was returned to the findChild() method when you call ConnectDAO.getSessionInstance() again in the populateDetails() method.

Since you are getting a LazyInitializationException the session that loaded the child has obviously been closed. The reason that it works when you print the debug statement is that this initializes the parent proxy while the session is still active. If you don't print the debug statement this initialization doesn't happen until the session has been closed.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 05, 2008 4:31 pm 
Regular
Regular

Joined: Tue Feb 19, 2008 6:05 pm
Posts: 82
Thanks for the quick reply. Could you please tell me how I may check if the session is new or if it has changed. Is there any id or attribute that determines when it was created? I will check try and check this out too.

I could not see any session.close() methods being called, although I have seen session.clear() or session.flush() methods being used in our application.

Thanks
Krishna


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 05, 2008 5:19 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Can you post the code in the ConnectDAO.getSessionInstance() method?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 05, 2008 7:02 pm 
Regular
Regular

Joined: Tue Feb 19, 2008 6:05 pm
Posts: 82
I am confident about this code though, that it returns an existing session rather than opening and creating a new one!

Code:
public class ConnectDAO {

   private static Session hibernateSession = null;

   public static Session getSessionInstance() {
      System.out.println("ConnectDAO getSessionInstance () method called.");
      try {
         // This step will read hibernate.cfg.xml and prepare hibernate for
         // use
         if (hibernateSession != null)
            return hibernateSession;
         else {
            SessionFactory sessionFactory = new Configuration().configure(
                  "hibernate.cfg.xml").buildSessionFactory();
            hibernateSession = sessionFactory.openSession();
            System.out
                  .println(" Creating Hibernate session from its factory.");
            return hibernateSession;
         }

      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      } finally {
         // Actual contact insertion will happen at this step
         // hibernateSession.flush();
         // hibernateSession.close();
      }
      return null;
   }

}


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 06, 2008 2:00 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Seems a bit weird that you are always using the same session. I can't explain why you get a LazyInitialisationException in this case.

On the other hand it is a good idea to have a single session in this way. The API documentation for the Session class (http://www.hibernate.org/hib_docs/v3/ap ... ssion.html) clearly states that a session is not thread-safe and can't be shared between threads. In the stacktrace in the first post I noticed that this is a Tomcat web application and I think you will be in big trouble if more than one request is made at the same time.

I recommend reading a few of the documents in the Transactional and system architecture design patterns section on the Hibernate wiki: http://www.hibernate.org/37.html


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.