1

I'm working on a project 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, 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.

Roman C
  • 49,761
  • 33
  • 66
  • 176
Mouad EL Fakir
  • 3,609
  • 2
  • 23
  • 37

2 Answers2

3

The order of filter chain is important. In your case the session should be opened before struts is executing actions and closed after that. The last thing is done by spring via managing Hibernate session. So, reorder filters and allow struts2 dispatcher accept requests from the first filter.

   <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>

 <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>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
  </filter-mapping>
Roman C
  • 49,761
  • 33
  • 66
  • 176
  • Thank's for the answer, i did exactly what you say but now i'm getting another error message: "No bean named 'sessionFactory' is defined" – Mouad EL Fakir Sep 28 '14 at 14:57
  • This message you can't get if you did what I said. If this message was before you did anything I said then better ask a new question. – Roman C Sep 28 '14 at 15:03
  • You didn't tell me where i must put this contextConfigLocation classpath:applicationContext.xml org.springframework.web.context.ContextLoaderListener i think this where this error come from – Mouad EL Fakir Sep 28 '14 at 15:07
  • No, didn't tell you that, because you didn't ask me so. Do you want to know where it should be? – Roman C Sep 28 '14 at 15:10
  • context-param should be before spring's stuff. Listeners should be after filters, if it matters. – Roman C Sep 28 '14 at 15:13
  • Anyway Thank you i'm trusting your answer, but i'm still doing something wrong :/ – Mouad EL Fakir Sep 28 '14 at 15:19
  • 2
    My answer is related to only one problem in your question if you have other problems you should ask them separately or your question becomes too broad. – Roman C Sep 28 '14 at 15:23
1

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

Community
  • 1
  • 1
Marek
  • 58
  • 1
  • 5