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

  • Unit tests and LazyInitializationException

    I'm using Hibernate & Spring and I'm looking for some best practices for writing unit tests. I'm currently getting a LazyInitializationException when executing this unit test:

    Code:
    public void testUserInRoleOk() throws Exception {
    		
    		WebUser user = this.userService.retrieveWebUser("[email protected]", "password");
    		assertTrue(this.userService.isUserInRole(user, WebRoleEnum.CUSTOMER));		
    	}
    The first line executes ok but then the exception is thrown in the implementation of "isUserInRole".

    The WebUser object has a Hibernate relationship with WebRole, there's a WebUser.getWebRoles method that returns a Set of WebRoles and that is exactly what the "isUserInRole" method is doing (and then getting the exception).

    I'm using a HibernateTransactionManager and TransactionInterceptor for both methods on the service:"retrieveWebUser" and "isUserInRole".

    Now when I deploy this on a web app I guess I would use the OpenSessionInViewInterceptor but what about for unit tests? Is there an elegant way to have a Session stay open for the duration of the test method? I have a feeling I may be missing something.

    Thanks
    Andres

  • #2
    You need to simulate the OpenSessionInViewInterceptor behaviour in your Unit Tests.
    I use the following class for Spring/Hibernate/JUnit tests

    Code:
    //Hibernate imports
    import net.sf.hibernate.FlushMode;
    import net.sf.hibernate.Session;
    import net.sf.hibernate.SessionFactory;
    
    //Spring imports
    import org.springframework.orm.hibernate.SessionFactoryUtils;
    import org.springframework.orm.hibernate.SessionHolder;
    import org.springframework.transaction.support.TransactionSynchronizationManager;
    
    //Taha imports
    import org.taha.spring.BaseSpringTest;
    
    /**
     * @author <a href="mailto&#58;[email protected]">Omar Irbouh</a>
     * @version 0.1
     * @since 2004.03.03
     */
    public abstract class BaseSpringHibernateTest extends BaseSpringTest &#123;
    
      protected static final String SESSION_FACTORY = "sessionFactory";
    
      protected SessionFactory sessionFactory = null;
    
      protected void setUp&#40;&#41; throws Exception &#123;
        super.setUp&#40;&#41;;
        sessionFactory = &#40;SessionFactory&#41; getApplicationContext&#40;&#41;.getBean&#40;SESSION_FACTORY&#41;;
        Session session = SessionFactoryUtils.getSession&#40;sessionFactory, true&#41;;
        session.setFlushMode&#40;FlushMode.NEVER&#41;;
        TransactionSynchronizationManager.bindResource&#40;sessionFactory, new SessionHolder&#40;session&#41;&#41;;
      &#125;
    
      protected void tearDown&#40;&#41; throws Exception &#123;
        SessionHolder sessionHolder = &#40;SessionHolder&#41; TransactionSynchronizationManager.unbindResource&#40;sessionFactory&#41;;
        SessionFactoryUtils.closeSessionIfNecessary&#40;sessionHolder.getSession&#40;&#41;, sessionFactory&#41;;
        super.tearDown&#40;&#41;;
      &#125;
    &#125;
    org.taha.spring.BaseSpringTest is a simillar abstract class responsible for building the ApplicatinContext. You can remove the dependance on BaseSpringTest and add a method getApplicationContext() that returns the ApplicationContext.

    HTH.

    Comment


    • #3
      Thanks! I also found a reference on the Hibernate boards:

      http://forum.hibernate.org/viewtopic.php?t=929167

      The example posted there does not have the line:

      Code:
      session.setFlushMode&#40;FlushMode.NEVER&#41;;
      Just curious on your thoughts on how FlushMode affects things.

      Comment


      • #4
        Good point!!!

        I use BaseSpringHibernateTest mainly in readonly + lazy initialization scenarios. I added this line to enforce no updates can be executed in the underlying code.

        Now that JŁergen added checkWriteOperationAllowed in HibernateTemplate, I no longer need to keep this line, and the class may serve for readonly/readwrite tests. So, please remove it if you want to use the class in your tests.

        Comment

        Working...
        X