Announcement Announcement Module
Collapse
No announcement yet.
LazyInitializationException and webflow Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • LazyInitializationException and webflow

    Hello,

    I've got something i can't explain:

    I'm trying
    to display elements (a list of elements) which are lazy loaded.
    after modification of those elements (and a submit), to recover those elements
    I use the openSessionInViewFilter

    It works fine with Spring MVC:
    I have a SimpleFormController where:
    in formBackingObject(...) i get an element (which contains the elements lazy loaded)
    i display the view
    in the onsubmit(...), i recover all i want and i can work with the collection which is now loaded
    I try to do that in webflow :
    I have a FormAction where :
    in setupForm(...) i get an element (which contains the elements lazy loaded)
    i display the view => elements lazy loaded are well displayed
    in the processSubmit(...), i recover the form (which is in flow scope) but i can't work with the collection because it was not loaded !!!
    i don't understand why the collection (lazy loaded) is displayed and the reason why i can work (i have a LazyInitializationException) with it in the method processSubmit(...)
    in fact in debug mode, we can see that the collection have not been loaded, it's very strange because this collection was displayed in the view !!!

    The way i recover the form in processSubmit(...) :
    Code:
    form = (SecondeReceptionForm) context.getFlowScope().getAttribute("secondeReceptionForm");
    in this form there is the element which contains the elements lazy loaded

    If anyone can help me, thank you very much.

  • #2
    Greeting!

    You are probably calling some getXXX on the loaded object after the hibernate session is closed.

    Curtney

    Comment


    • #3
      Not entirely sure but I would expect funny things to happen to Hibernate backed objects (if you are using OSIV which you are) if you put them in flow scope.

      Anything in flow scope (actually this may depend upon your configuration) gets serialised, so you hibernate objects and their backing session will be serialised, when you next access the flow, the objects will be deserialised but the session will no longer be valid.

      This might all be a croc of poo, but it might just be right

      Comment


      • #4
        Can you post your entire stack trace as well please

        Comment


        • #5
          Originally posted by curtney
          You are probably calling some getXXX on the loaded object after the hibernate session is closed.
          That's right, but what i try to do is to make it work fine as i done it with Spring MVC

          Originally posted by yatesco
          the objects will be deserialised but the session will no longer be valid.
          Yes, it's exactly what happened. In processSubmit(...) i can see that the collection have not been initialized and that the Session (hibernate) is null.
          I don't understand why the collection is not initialized because it is correctly displayed in the view (jsp) !!!

          Originally posted by yatesco
          Can you post your entire stack trace as well please
          Code:
          org.springframework.webflow.ActionExecutionException: Exception thrown executing action 'com.auchan.protoSpring.web.controller.flow.SecondeReceptionController@1cd1d94' in state 'traiterSecondeReception' of flow 'secondereception'; nested exception is net.sf.hibernate.LazyInitializationException: Failed to lazily initialize a collection - no session or session was closed
          net.sf.hibernate.LazyInitializationException: Failed to lazily initialize a collection - no session or session was closed
          	at net.sf.hibernate.collection.PersistentCollection.initialize(PersistentCollection.java:209)
          	at net.sf.hibernate.collection.PersistentCollection.read(PersistentCollection.java:71)
          	at net.sf.hibernate.collection.Bag.get(Bag.java:421)
          	at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:672)
          	at org.springframework.beans.BeanWrapperImpl.getNestedBeanWrapper(BeanWrapperImpl.java:552)
          	at org.springframework.beans.BeanWrapperImpl.getBeanWrapperForPropertyPath(BeanWrapperImpl.java:530)
          	at org.springframework.beans.BeanWrapperImpl.getBeanWrapperForPropertyPath(BeanWrapperImpl.java:531)
          	at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:726)
          	at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:890)
          	at org.springframework.beans.BeanWrapperImpl.setPropertyValues(BeanWrapperImpl.java:917)
          	at org.springframework.validation.DataBinder.applyPropertyValues(DataBinder.java:424)
          	at org.springframework.validation.DataBinder.doBind(DataBinder.java:331)
          	at org.springframework.web.bind.WebDataBinder.doBind(WebDataBinder.java:111)
          	at org.springframework.validation.DataBinder.bind(DataBinder.java:316)
          	at org.springframework.webflow.action.FormAction.doBind(FormAction.java:684)
          	at org.springframework.webflow.action.FormAction.bind(FormAction.java:590)
          	at com.auchan.protoSpring.web.controller.flow.SecondeReceptionController.processSubmit(SecondeReceptionController.java:60)
          	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:324)
          	at org.springframework.webflow.util.DispatchMethodInvoker.dispatch(DispatchMethodInvoker.java:231)
          	at org.springframework.webflow.action.MultiAction.doExecute(MultiAction.java:138)
          	at org.springframework.webflow.action.AbstractAction.execute(AbstractAction.java:225)
          	at org.springframework.webflow.ActionExecutor.execute(ActionExecutor.java:65)
          	at org.springframework.webflow.AnnotatedAction.execute(AnnotatedAction.java:154)
          	at org.springframework.webflow.ActionExecutor.execute(ActionExecutor.java:65)
          	at org.springframework.webflow.ActionState.doEnter(ActionState.java:303)
          	at org.springframework.webflow.State.enter(State.java:189)
          	at org.springframework.webflow.Transition.execute(Transition.java:273)
          	at org.springframework.webflow.TransitionableState.onEvent(TransitionableState.java:230)
          	at org.springframework.webflow.execution.FlowExecutionImpl.signalEvent(FlowExecutionImpl.java:341)
          	at org.springframework.webflow.execution.FlowExecutionManager.onEvent(FlowExecutionManager.java:446)
          	at org.springframework.webflow.execution.FlowExecutionManager.onEvent(FlowExecutionManager.java:389)
          	at org.springframework.webflow.execution.servlet.ServletFlowExecutionManager.handle(ServletFlowExecutionManager.java:77)
          	at org.springframework.webflow.mvc.FlowController.handleRequestInternal(FlowController.java:138)
          	at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:139)
          	at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:44)
          	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:684)
          	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:625)
          	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:392)
          	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:357)
          	at javax.servlet.http.HttpServlet.service(HttpServlet.java:763)
          	at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
          	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:284)
          	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:204)
          	at org.springframework.orm.hibernate.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:174)
          	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
          	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:233)
          	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:204)
          	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:257)
          	at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151)
          	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:564)
          	at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:245)
          	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:199)
          	at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151)
          	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:564)
          	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:195)
          	at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151)
          	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:164)
          	at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:149)
          	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:564)
          	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:156)
          	at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151)
          	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:564)
          	at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:972)
          	at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:206)
          	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:828)
          	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:700)
          	at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:584)
          	at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
          	at java.lang.Thread.run(Thread.java:534)

          Comment


          • #6
            Can you post your flow and relevant portions of your code?

            Curtney

            Comment


            • #7
              I know the source of the problem :
              I use (try to )both :
              1. OSIV (Interceptor on urlMapping bean) : Lazy Loading
              2. OpenSessionInFlowListener (OSIF, listener on the FlowController) : share the same session along of a flow, it's a listner driven by FlowExecutionListenerAdapter (envent on a flow) (OSIF)

              OSIV and OSIF share the same sessionFactory

              Shéma :
              http://fredthieum.free.fr/gallery/ga...ernateFlow.jpg


              Cases :
              1. OSIV alone : I can do Lazy Loading but not share a session along a flow
              2. OSIF alone : I can share a session along a flow but not lazy loading
              3. OSIV + OSIF : I can share a session along a flow but i have a NPE in the OSIV Interceptor because the OSIF disconnect the hibernate session.

              I tried to not disconnect the session in the OSIF but the session is put in the Flow Scope so it's serialized and a session can't be serialized if it is
              connected....

              It seems that i can't do Lazy Loading (OSIF) + share session along a flow (OSIF). May be i have to subclass the OSIV Interceptor to have a unique point where i manage the session and in case of flow, to put the session (hibernate) in the httpsession. My new problem here is that i don't know how to distinguish who need to share a session and who don't need...

              Can someone tell me if i'm right in my explanation and how i can do Lazy Loading AND share a session along a flow ? Thanks !!!

              Comment


              • #8
                Originally posted by Thieumdesp
                Can someone tell me if i'm right in my explanation and how i can do Lazy Loading AND share a session along a flow ? Thanks !!!

                One advantage of the OpenSessionInFlowListener (OSIF) is that it prevents LazyLoad exceptions for all objects created in the flow's hibernate session. Furthermore, it allows optional sharing of a hibernate session between parent and child flows. If you are getting a lazy load exception while using OSIF, I would suspect that one of the following conditions exist:

                1. The object that's causing the lazy load exception was loaded in a session outside the scope of the flow. This will happen if, for example, you load a user object at login and store it in your HTTP session, then later try to reference a proxied association from the user in an action method.

                2. The object that's causing the lazy load exception was loaded in a parent flow and you have not configured the parent flow to allow child flows to share the parent's hibernate session. This means that the parent flow and the child flow have different hibernate sessions and that objects shared between the flows are susceptible to lazy load exceptions. You may share a parent flow's hibernate session with a child flow by adding the following to your parent's flow.xml file:
                <property name="subflowsParticipateInApplicationTransaction" value="true"/>

                -Alex

                Comment


                • #9
                  Originally posted by akw
                  One advantage of the OpenSessionInFlowListener (OSIF) is that it prevents LazyLoad exceptions for all objects created in the flow's hibernate session. Furthermore
                  When i use only OSIF

                  Unfortunately, as the hibernate session has been disconnected in the method requestProcessed(...), it can't be use by the view to do lazy loading. And i'm not in the two cases you described :
                  1 : i load the object in an FormAction which is an <action-state/> of the flow
                  2 : i'm not in a subflow
                  But may be i do a bad use...

                  In response of http://forum.springframework.org/sho...3386#post43386 :
                  The aim is to do lazy loading everywhere it is necessary. it's a good idea to use an appropriate mapping, but the problem is i can't do lazy loading with OSIF.

                  Comment


                  • #10
                    Originally posted by Thieumdesp
                    [B]Unfortunately, as the hibernate session has been disconnected in the method requestProcessed(...), it can't be use by the view to do lazy loading.
                    This is by design. We want the session to be disconnected at the completion of an HTTP request. When the next request arrives, the session will be reconnected again (see the sessionActive() method). All view rendering occurs between the time the request arrives and the time the request is complete. During this time, the hibernate session is open and connected. You can go on using objects loaded in that session (even if they were loaded in a previous request) as you would normally without the risk of lazy load exceptions.

                    Can you give me more information about what behavior you're seeing? Your description of the problem seems to imply that the requestProcessed() method is prematurely disconnecting the session.

                    Just to reiterate, the OpenSessionInViewFilter (or Interceptor) and the OpenSessionInFlowListener cannot both operate on the same HTTP request. You have to choose one or the other - this is where a filter mapping would be handy. Are you certain that you have this setup correctly?

                    -Alex

                    Comment


                    • #11
                      Originally posted by akw
                      All view rendering occurs between the time the request arrives and the time the request is complete. During this time, the hibernate session is open and connected. You can go on using objects loaded in that session (even if they were loaded in a previous request) as you would normally without the risk of lazy load exceptions.
                      It seems that the requestProcessed(...) occurs before the real end of the HTTRequest because when i use OSIF alone (i mean whithout OSIV), the lazy loading doesn't work, i mean when i try to access a lazy collection in the view (a jsp) i have a LazyInitializationException.

                      Originally posted by akw
                      Can you give me more information about what behavior you're seeing? Your description of the problem seems to imply that the requestProcessed() method is prematurely disconnecting the session.
                      You're right. Describe what i try to do may clarify the situation !!!
                      In fact i just want to be able to do lazy loading everywhere (in the views, flow or not flow) and to have (for some flows, i know we can avoid listener with FlowExecutionListenerCriteria) long session per flow (what you do fine with OSIF )

                      I can do what i want with that :
                      http://opensource2.atlassian.com/con...on?pageId=1447
                      + a listener extended FlowExecutionListenerAdapter which deals with the event :
                      1. sessionStarted
                      2. sessionEnded
                      What do you think of that ?
                      In any case, thanks for your response and the time you spend !!!

                      Comment


                      • #12
                        Originally posted by Thieumdesp
                        It seems that the requestProcessed(...) occurs before the real end of the HTTRequest because when i use OSIF alone (i mean whithout OSIV), the lazy loading doesn't work, i mean when i try to access a lazy collection in the view (a jsp) i have a LazyInitializationException.
                        Interesting that you are having this problem. I do not see the same behavior here, using the OpenSessionInFlowListener. Are you absolutely certain that the requestProcessed() method is being called prior to the view being rendered? Or are you saying that simply because you are getting a LazyInitializationException? What version of SWF are you using? Maybe one of the SWF team has an idea about the possibility that requestProcessed() is being called prior to view rendering? I would say this isn't very likely - but I've been wrong many times before.

                        You might try debugging to be sure that the Session instance held in flow scope is the same session that is generating the lazy load exception. There is a possibility that you're somehow working with two different Sessions, one in flow scope (which is open), and one held by the lazy initializer (which is closed). There is also a possibility that the Session instances are one and the same, and that it is being closed someplace other than in the requestProcessed() method.

                        Originally posted by Thieumdesp
                        I can do what i want with that :
                        http://opensource2.atlassian.com/con...on?pageId=1447
                        + a listener extended FlowExecutionListenerAdapter which deals with the event :
                        1. sessionStarted
                        2. sessionEnded
                        What do you think of that ?
                        This is certainly an option that might work well for you. The OpenSessionInFlowListener affords a few advantages that this method does not (although it could probably be adapted quite well).

                        First, the OSIFL tracks your session on a per-flow basis - that means that it gets serialized with your flow and that you can have multiple sessions open for different flows. This also makes it somewhat simpler to 'share' a session with subflows so that you can map domain objects between flows (using the attribute mapper) without concern for a closed session.

                        Second (and this might be a good thing or a bad thing depending on your circumstances), the OSIFL eliminates the need to manually manage the opening and closing of your Hibernate Session. It works on the assumption that a single instance of a flow in your application should have one Hibernate Session that is automatically opened when the flow starts and closed when the flow ends. This basic concept means that you avoid complications that can arise when managing your Session manually.

                        Anyhow, I encourage you to find a solution that works well for you without too much hassle. It seems like you've spent a good deal of time trying to get the OSIFL working, to no avail. And without examining your app closely, I cannot tell you why you are getting a LazyInitializationException. I can tell you that the OSIFL seems to be working well for us and is successfully performing the task you describe. We're even nesting flows (with domain objects stored in flow scope) and using the same session across all of them, without significant problems. If you think you've found a bug in the OpenSessionInFlowListener, please let me know. I don't claim that it's perfect.

                        Please feel free to continue this discussion. I would love for you to use the OSIFL, if you can make it do what you want. Consequently, I'm happy to help however I can.

                        -Alex
                        Last edited by akw; Dec 12th, 2005, 09:03 PM.

                        Comment


                        • #13
                          Originally posted by akw
                          What version of SWF are you using?
                          I'm using PR5

                          Originally posted by akw
                          Are you absolutely certain that the requestProcessed() method is being called prior to the view being rendered? Or are you saying that simply because you are getting a LazyInitializationException?
                          You might try debugging to be sure that the Session instance held in flow scope is the same session that is generating the lazy load exception. There is a possibility that you're somehow working with two different Sessions, one in flow scope (which is open), and one held by the lazy initializer (which is closed). There is also a possibility that the Session instances are one and the same, and that it is being closed someplace other than in the requestProcessed() method.
                          what i am (almost) certain :
                          1. all bean dealing with hibernate session is using the same sessionFactory bean
                          2. the Session instance is the same in :
                            • the method sessionActive of OSIF
                            • the manager which recover the object via Hibernate
                            • the method requestProcessed of OSIF
                          3. the Session instance is not closed but disconnected
                          4. the method which recover the lazy collection (this method is called by the view) to display in the view is called AFTER the requestProcessed of OSIF, the Session instance attached to this lazy collection is the same instance BUT this Session instance is disconnected and so i have the error :
                            Code:
                            net.sf.hibernate.LazyInitializationException: Failed to lazily initialize a collection - session is disconnected

                          a schema of what i think is happening for me :
                          http://fredthieum.free.fr/gallery/ga...sionclosed.jpg

                          Originally posted by akw
                          Maybe one of the SWF team has an idea about the possibility that requestProcessed() is being called prior to view rendering? I would say this isn't very likely - but I've been wrong many times before.
                          Yes, what is important to know is if the requestProcessed(...) event of the FlowExecutionListener occurs before or after the view rendered.
                          Can someone of the SWF team answer to this question ? (may be do a new post ?)
                          => I do : new post

                          Originally posted by akw
                          I can tell you that the OSIFL seems to be working well for us and is successfully performing the task you describe.
                          You success to do lazy loading in flow using only OSIF ?

                          Originally posted by akw
                          Anyhow, I encourage you to find a solution that works well for you without too much hassle. It seems like you've spent a good deal of time trying to get the OSIFL working, to no avail. And without examining your app closely, I cannot tell you why you are getting a LazyInitializationException. We're even nesting flows (with domain objects stored in flow scope) and using the same session across all of them, without significant problems. If you think you've found a bug in the OpenSessionInFlowListener, please let me know. I don't claim that it's perfect.
                          Please feel free to continue this discussion. I would love for you to use the OSIFL, if you can make it do what you want. Consequently, I'm happy to help however I can.
                          I find your solution very useful (you're right with the danger of manually manage the opening and closing of the Hibernate Session) and that's why i try to do it work !!!
                          The solution i tell you works but i find it very very basic !!!

                          @akw : i do a very simple application using hsldb to illustrate the lazy exception using webflow and OSIF, is there a way i give you this app ? for example i can give you a zip (or rar) of the tree of my eclipse project (tomcat project) ?
                          Last edited by Thieumdesp; Dec 13th, 2005, 11:39 AM.

                          Comment


                          • #14
                            Originally posted by Thieumdesp
                            @akw : i do a very simple application using hsldb to illustrate the lazy exception using webflow and OSIF, is there a way i give you this app ? for example i can give you a zip (or rar) of the tree of my eclipse project (tomcat project) ?
                            Sure. You can send it to me at via email. Please do not include the dependencies (jar files).

                            My email address starts with alexkw, and ends with mac dot com.

                            Comment


                            • #15
                              Originally posted by Thieumdesp
                              I'm using PR5
                              You success to do lazy loading in flow using only OSIF ?
                              Yes, we are using the OSIFL to do manage Hibernate Sessions in our flows. Almost every association is proxied, so I would imagine that there is some lazy loading going on in there somewhere.

                              -Alex

                              Comment

                              Working...
                              X