7 Replies Latest reply on Apr 20, 2009 4:51 PM by david.spark

    Struggling with LazyInitializationException

      Hi, I'm hoping someone can help me understand Seam and LIE.


      I have this code:


      FeedbackType attitude = webUser.getClientContact().getClient().getBranch().getClientFeedbackTypeAttitude();
           for(EventStaff eventStaff : currentEvent.getEventStaff()){
                for(StaffBooking staffBooking : eventStaff.getStaffBookings()){
                     for(StaffFeedback staffFeedback : staffBooking.getStaffFeedback()){
                          if(staffFeedback.getFeedbackType().getId().equals(attitude.getId())){
                                    staffBooking.setTempFeedbackRating(0);
                          }
                     }
                }
           }



      with the entity bean having the following decleration:


      @OneToOne
      @JoinColumn(name="ClientFeedbackTypeAttitude")
      private FeedbackType clientFeedbackTypeAttitude;
      



      In certain situations when I load the page that this code gets trigger from I get the following error:


      13:53:56,442 ERROR [LazyInitializationException] 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.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:166)
           at uk.co.splendid.sms.feedback.FeedbackType_$$_javassist_423.getId(FeedbackType_$$_javassist_423.java)
           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 javax.el.BeanELResolver.getValue(BeanELResolver.java:62)
           at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:53)
           at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
           at org.jboss.el.parser.AstPropertySuffix.getValue(AstPropertySuffix.java:53)
           at org.jboss.el.parser.AstValue.getValue(AstValue.java:67)
           at org.jboss.el.parser.AstEqual.getValue(AstEqual.java:22)
      ...
           at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
           at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
           at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
           at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
           at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
           at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
           at java.lang.Thread.run(Thread.java:619)
      13:53:56,458 ERROR [STDERR] 17-Apr-2009 13:53:56 com.sun.facelets.FaceletViewHandler handleRenderException
      SEVERE: Error Rendering View[/client/bookingTimesheet.xhtml]
      javax.faces.FacesException: javax.el.ELException: /client/bookingTimesheet.xhtml @103,137 rendered="#{staffFeedbackComment.feedbackType.id == webUser.clientContact.client.branch.clientFeedbackTypeComment.id}": Error reading 'id' on type uk.co.splendid.sms.feedback.FeedbackType_$$_javassist_423
           at javax.faces.component.UIComponentBase.isRendered(UIComponentBase.java:393)
           at org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:276)
           at org.ajax4jsf.renderkit.html.RepeatRenderer$1.process(RepeatRenderer.java:53)
           at org.ajax4jsf.model.SequenceDataModel.walk(SequenceDataModel.java:101)
           at org.ajax4jsf.component.UIDataAdaptor.walk(UIDataAdaptor.java:1151)
           at org.ajax4jsf.renderkit.html.RepeatRenderer.encodeChildren(RepeatRenderer.java:59)
           at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:837)
           at org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:282)
           at org.ajax4jsf.renderkit.html.RepeatRenderer$1.process(RepeatRenderer.java:53)
           at org.ajax4jsf.model.SequenceDataModel.walk(SequenceDataModel.java:101)
      ...



      I don't really understand what is happening here, I've tried various things but all I've managed to do is change the point at which the error shows up. It only happens when visiting the page after visiting the same page for an item that does not result in the first section of code being fully executed. It seems like a fairly standard error but I just can't figure out how to fix it.


      Thanks
      David

        • 1. Re: Struggling with LazyInitializationException
          javacoryd

          If you look at your stack trace you will see the LIE happens when you are rendering the .xhtml page:


          rendered="#{staffFeedbackComment.feedbackType.id == webUser.clientContact.client.branch.clientFeedbackTypeComment.id}": Error reading 'id' on type uk.co.splendid.sms.feedback.FeedbackType_$$_javassist_423


          One of those containing entities ( staffFeedbackComment or ...client.branch ) is NOT managed ( in the EntityManager ) at the time this EL expression is being executed.


          Cory.

          • 2. Re: Struggling with LazyInitializationException

            OK, thanks for that! The good news is that I've fixed the problem, the bad news is that I'm still confused as I don't understand why it does work.


            What I did was change the fetch type for the OneToOne join from branch to clientFeedbackTypeComment from Lazy to Eager. What I don't understand is that all the way down the tree starting from webUser the fetch types are all Lazy, how come this last one needs to be Eager?


            I'm also concerned that this solution is not ideal as if I were to solve all problems like this then I would end up loading the entire data tree! Is there some way to keep the fetch type as Lazy and get it loading at the relevant time to avoid the LIE?


            Thanks again
            David

            • 3. Re: Struggling with LazyInitializationException
              javacoryd

              A couple of questions:


              1) Are you using a seam-managed entity manager ( one defined in components.xml ) to load your entities?


              2) Is the webUser an entity you are putting into SESSION scope?


              Thanks,


              Cory.

              • 4. Re: Struggling with LazyInitializationException
                javacoryd

                My hunch is the webUser gets loaded and put into SESSION scope.  If you don't hydrate all of the relationships at the time the webUser is loaded, and then attempt to retrieve a relationship that has not been loaded on a subsequent request, you get this error.


                The reason for this is for lazy initialization to work the entity needs to be backed by an open entity manager ( persistence context ).  The Seam managed persistence context only stays open for the life of a conversation ( be it a long running conversation or a temporary one ).


                In your case, your relationship is not loaded because the entity manager is closed when you ask for it.


                Cory.

                • 5. Re: Struggling with LazyInitializationException

                  You are correct on both counts, thanks for the insight into this.


                  So there is no way using a Seam managed persistence context to inject a particular entity (i.e. webUser) into different conversations and Lazily load relationships? One of the reasons I am keen to do this is that my database can be updated by other systems so I may be showing out of date data if I do not refresh the relationship with each new conversation.


                  Thanks, David

                  • 6. Re: Struggling with LazyInitializationException
                    javacoryd

                    Well, the only way I know of to get around the issue is to re-read the webUser by ID with each conversation.  From your use case, you would have to do that anyway if you want to pickup changes made to the DB from other systems.


                    Cory.

                    • 7. Re: Struggling with LazyInitializationException

                      OK, thanks for all your help. I will try that out and no doubt have another post or two if I run into problems! :-)