Announcement Announcement Module
Collapse
No announcement yet.
FYI: OpenSessionInView, LazyInitializationException, and Flow scope form objects Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • FYI: OpenSessionInView, LazyInitializationException, and Flow scope form objects

    I offer this post more as a how-to than a request for help, but if you know of a better way, do share:

    I had a persisted object that I was keeping in the Flow Scope because I needed to manipulate different parts on different requests. The problem I faced is that in a subsequent request when I need to maninpulate the Set my persisted object contained I would encounter an LazyInitializationException (LIE) due to the Session being closed, even though I had been using the OpenSessionInViewFilter (OSIV).

    Even though I was using the OSIV and had a Session, that didn't mean that my object would "know" to use that Session to complete its lazy initialization.

    So, I had to reattach the object, and this is how I did it: FlowExecutionListener

    HTML Code:
    	<bean id="hibernateFlowListener" class="net.cya.spring.webflow.HibernateFlowListener">
    		<property name="hibernateTemplate"><ref bean="hibernateTemplate"/></property>
    	</bean>
    
    	<bean name="accountFormController" class="org.springframework.webflow.mvc.FlowController">
    		<!-- property name="flow"><ref bean="accountFlow"/></property-->
    		<property name="flowExecutionManager">
    			<bean class="org.springframework.webflow.execution.servlet.ServletFlowExecutionManager">
    				<property name="flow" ref="accountFlow"/>
    				<property name="listener"><ref bean="hibernateFlowListener"/></property>
    			</bean>
    		</property>
    	</bean>
    Code:
    public class HibernateFlowListener extends FlowExecutionListenerAdapter {
    	public void loaded(FlowExecutionContext context, Serializable id) {
    		// get our form object
    		AccountFormObject afo = (AccountFormObject)context.getActiveSession().getScope().get("formObject");
    		
    		// get our current session
    		Session session = hibernateTemplate.getSessionFactory().getCurrentSession();
    		
    		// reattach our object to session
    		// EDIT: removed the following and replaced with the following line--see kenevel's response below:
    		// session.lock(afo.getAccount(), LockMode.NONE);
    		
    		session.replicate(afo.getAccount(), ReplicationMode.OVERWRITE);
    		
    	}
    	
    	private HibernateTemplate hibernateTemplate;
    	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
    		this.hibernateTemplate = hibernateTemplate;
    	}
    }
    (AccountFormObject is the form backing object I use and it contains an Account, the persisted object with the lazy initialization)
    Last edited by daniel.smith; Feb 27th, 2006, 10:47 AM.

  • #2
    Surely if you modify your object you will get a HibernateException when it dirty-checks your object for changes when you call .lock(...)?

    Comment


    • #3
      Greetings!

      Just to add to what your saying Daniel. You beat me to the punch I myself had a similar issue when my subflows were serialized and then deserialized. Your persistent Set (See hinerate PersistentSet or its superclass), upon serialization, losses the current session, since it is declared as transient. Therefore, there is an explicit need to reattach your object to the current session, especially objects that have collections, like Sets.

      Using a FlowExecutionListener is a good option. I have not done so, but I am thinking I should. What I did was to refresh my object (doing a LockMode.READ), thus associating to the currernt session, just when I am about to update it. I do a LockMode.READ because I want to bypass the secondary cache and force a database read (don't want stale data). I like the manual approach, but the downside (perhaps a downside) it forces you to be aware of your persistent object state.

      Comment


      • #4
        Have you considered using Conversation scope instead of Flow scope? I believe this would avoid serialization/deserialization problems.

        Comment


        • #5
          Hmm. I forgot about this new addition (Conversation scope) to SWF. I will look into it.

          Thanks for the tip.

          Comment


          • #6
            curtney and mihail,

            this is the first i have heard of such. do you have any links to some good documentation on this? thanks in advance

            Comment


            • #7
              The following thread discusses about conversation scope:

              http://forum.springframework.org/showthread.php?t=21912

              Also look at the sellitem sample application for an example.

              Have fun,
              Mihail

              Comment

              Working...
              X