Spring OpenSessionInViewFilter with @Transactional annotation

Gautam picture Gautam · May 26, 2014 · Viewed 10.9k times · Source

This is regarding Spring OpenSessionInViewFilter using with @Transactional annotation at service layer.

i went through so many stack overflow post on this but still confused about whether i should use OpenSessionInViewFilter or not to avoid LazyInitializationException It would be great help if somebody help me find out answer to below queries.

  • Is it bad practice to use OpenSessionInViewFilter in application having complex schema.
  • using this filter can cause N+1 problem
  • if we are using OpenSessionInViewFilter does it mean @Transactional not required?

Below is my Spring config file

<context:component-scan base-package="com.test"/>
<context:annotation-config/>
 <bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="resources/messages" />
        <property name="defaultEncoding" value="UTF-8" />
    </bean>
 <bean id="propertyConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
        p:location="/WEB-INF/jdbc.properties" />
 <bean id="dataSource"
        class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
        p:driverClassName="${jdbc.driverClassName}"
        p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
        p:password="${jdbc.password}" />
       <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />     
        <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
        </property>
        <property name="configurationClass">
            <value>org.hibernate.cfg.AnnotationConfiguration</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${jdbc.dialect}</prop>
                <prop key="hibernate.show_sql">true</prop>
                <!--
                <prop key="hibernate.hbm2ddl.auto">create</prop>
                 -->
            </props>
        </property>
    </bean>
 <tx:annotation-driven /> 
 <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />

  </bean>

Answer

Fernando Rincon picture Fernando Rincon · May 27, 2014

OpenSessionInView is a servlet filter than just Open a hibernate session and store it in the SessionHolder for the thread that is serving the request. With this session opened, hibernate can read the Lazy initialized collections and objects when you use this in the rendering stage of the request. This session can be accessed when you invoke SessionFactory.getCurrentSession().

But, OpenSessionInView just opens the session and it doesn't begin any transactions. With a session opened you can read objects from database but, if you want to do something in a transaction you need @Transactional annotations or other mechanism to demarcate the begin and the end of the transaction when you want.

Then the answer of the questions:

Is it bad practice to use OpenSessionInViewFilter in application having complex schema.

This is a good practice if you need avoid the LazyInitializationException and the overload is just open new Hibernate Session and close it at the end of the request for each request.

Using this filter can cause N+1 problem

I use this filter in many projects and not cause any problem.

if we are using OpenSessionInViewFilter does it mean @Transactional not required?

No. You only have a Hibernate Session opened in the SessionHolder of the thread, but if you need Transactions you need put @Transactional.