Results 1 to 7 of 7

Thread: Revisiting our old friend LazyInitialization Exception

Hybrid View

  1. #1

    Default 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 bill.may@synesis7.com; Jan 17th, 2006 at 05:34 PM.

  2. #2
    Join Date
    Aug 2004
    Location
    San Francisco
    Posts
    423

    Default

    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

  3. #3
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    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);
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  4. #4

    Default

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

    Again, thank you very much!

  5. #5
    Join Date
    Dec 2005
    Location
    U-241
    Posts
    237

    Default

    Oh yeah, those guys are HIDING this kind of info in things called 'BOOKS'
    Spring, it's a wonderful thing...

  6. #6

    Default

    Quote Originally Posted by Arno Werr
    Oh yeah, those guys are HIDING this kind of info in things called 'BOOKS'

    Hey now, don't be a hater!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •