Announcement Announcement Module
Collapse
No announcement yet.
Revisiting our old friend LazyInitialization Exception Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Revisiting our old friend LazyInitialization Exception

    The following is my code.

    Code:
    public final void testApproveDocApprovalWorkFlowItem()
        {    
            
            ApplicationContext context = null;
            
            try
            {
                context = new ClassPathXmlApplicationContext("applicationContext.xml");
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            
            DocApprovalWorkflowDAO docApprovalDao = (DocApprovalWorkflowDAO)context.getBean("DocApprovalWorkflowDao");
    
            docApprovalDao.approveDocApprovalWorkFlowItem(id.intValue());
            
            DocApprovalWorkflow obj = docApprovalDao.load(id);
            boolean result = obj.isApproved().booleanValue();
            assertTrue(result);
            
        }
    The applicationContext.xml

    Code:
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
        "http://www.springframework.org/dtd/spring-beans.dtd"[
        <!ENTITY DataSourceBean "org.apache.commons.dbcp.BasicDataSource">
        <!ENTITY LocalSessionFactoryBean "org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    	<!ENTITY HibernateTransactionManager "org.springframework.orm.hibernate3.HibernateTransactionManager">
      
    ...
     <!-- Hibernate SessionFactory -->
        <bean id="sessionFactory" class="&LocalSessionFactoryBean;">
            <property name="mappingDirectoryLocations">
            	<list>
            		<value>classpath:com/synesis7/i3/model/hibernate/</value>
            	</list>
            </property>
            <property name="hibernateProperties">
            	<props>
            		<prop key="hibernate.cglib.use_reflection_optimizer">false</prop>
            		<prop key="hibernate.show_sql">true</prop>
             		<prop key="hibernate.default_schema">WES</prop>
            		<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>      
            	</props>
            </property>
            <property name="dataSource">
            	<ref bean="dataSource"/>
            </property>
        </bean>
    
    ... 
    
    <bean id="abstractSessionFactoryHost" abstract="true">
    		<property name="sessionFactory" ref="sessionFactory" />
    	</bean>
    	
    	<bean id="transactionManager" class="&HibernateTransactionManager;" parent="abstractSessionFactoryHost" />
    	
    	<bean id="DocApprovalWorkflowDao" class="&DocApprovalWorkflowDAOHibernate;"
    	parent="abstractSessionFactoryHost" />
    Code:
    org.hibernate.LazyInitializationException: could not initialize proxy - the owning Session was closed
    	at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:56)
    Why OH why, do I get a Lazy Initialization error on the line...

    boolean result = obj.isApproved().booleanValue();

    That just seems silly to me. At that point, I am using my POJO that represents that DB table. Spring and Hibernate have done their work for me. What is the correct way to handle this?

    Thank you.
    Last edited by [email protected]; Jan 17th, 2006, 05:34 PM.

  • #2
    Bill,

    Reading the reference documentation of Hibernate finds a potential answer to your problem. I quote:

    "If the class is mapped with a proxy, load() just returns an uninitialized proxy and does not actually hit the database until you invoke a method of the proxy."

    I take it your class is mapped as a proxy. So, since your test code is not running in a transaction (or at least it dosen't look like it) when you call the isApproved method you get the uninitialized proxy error.

    Personally, I'd change your testing stategy. I'd write a unit test in which i would mock out the dao's to return a DocApprovalWorkflow with known values. This enables the testing of the logic of the object graph manipulation without the database being involved.

    I'd then write an integration test that runs the methods against the database with transactions declared. These tests would aim to test the persistance parts, including, if needed, cases to test transaction failures and concurrency violations.

    Jonny

    Comment


    • #3
      Bill, jwray is right. The load vs get actually has been discussed quite a few times on the forums - you will receive the exception even if the session is opened but the object is not found.
      See the hb javadoc and do a simple test (inside a HB template if you'd like).
      From the hb sources:

      Object result = listeners.getLoadEventListener().onLoad(event, LoadEventListener.LOAD);
      ObjectNotFoundException.throwIfNull(result, id, entityName);

      Comment


      • #4
        Thanks alot guys... What do you know, pg 140 of Hibernate In Action talks about this.

        Again, thank you very much!

        Comment


        • #5
          Oh yeah, those guys are HIDING this kind of info in things called 'BOOKS'http://scosoft.com/s/h/3cd3078b.gif
          http://scosoft.com/s/a/5da69969.gif

          Comment


          • #6
            Originally posted by Arno Werr
            Oh yeah, those guys are HIDING this kind of info in things called 'BOOKS'http://scosoft.com/s/h/3cd3078b.gif
            http://scosoft.com/s/a/5da69969.gif

            Hey now, don't be a hater!

            Comment


            • #7
              http://scosoft.com/s/j/5dacd0db.gif

              Comment

              Working...
              X