javaspringhibernatestruts2open-session-in-view

How to use Open Session in View pattern in Struts 2?


I'm working on a project which is using Hibernate for persisting and Struts 2 for the view pattern.

My configuration files are:

web.xml:

<?xml version="1.0" encoding="UTF-8"?>

 <web-app>
     //......
     //.....
     <filter>
        <filter-name>struts2</filter-name>
        <filter-class>
          org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
        </filter-class>
      </filter>
      <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>
      
      <!-- The defintion of the root Spring Container shared by all Servlets and Filters -->
      <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
      </context-param>
      <!-- Creates the spring Container shared by all servlet and filters -->
      <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
      
       <filter> <!-- Get spring to keep the session open for the whole request, so hibernate's lazy loads work -->
        <filter-name>openSessionInViewFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>openSessionInViewFilter</filter-name>
        <url-pattern>/*</url-pattern> 
      </filter-mapping>
    </web-app>

applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans >
//.......
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/DB_TEST"></property>
        <property name="username" value="root"></property>
        <property name="password" value=""></property>
    </bean>
    
    <bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
        <property name="persistenceXmlLocations">
            <list>
                <value>classpath*:META-INF/persistence.xml</value>
            </list>
        </property>
        <property name="defaultDataSource" ref="dataSource"></property>
    </bean>
    
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitManager" ref="persistenceUnitManager"></property>
    </bean>
    
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"></property>
    </bean>
    
    <tx:annotation-driven transaction-manager="transactionManager" />
    <context:annotation-config></context:annotation-config>
</beans>

My problem is, I can't keep Hibernate session open in the view pattern of Struts 2, that means when I try to load some data, that are not already initialized with Hibernate (like collections for example), I get the org.hibernate.LazyInitializationException, so after doing some research, I found that I must add this scope in web.xml to keep the session open in the view pattern.

Scope:

<filter> <!-- Get spring to keep the session open for the whole request, so Hibernate's lazy loads work -->
    <filter-name>openSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>openSessionInViewFilter</filter-name>
    <url-pattern>/*</url-pattern> 
  </filter-mapping>

But even with this, I still have the same problem, so can anyone tell me what I'm doing wrong?


Solution

  • I've had similar problem some time ago, and to resolve this I used hibernate.enable_lazy_load_no_trans property instead of OpenSessionInView pattern. More informations about LazyInitializationException you can find here or here