如何在Struts 2中使用Open Session in View模式?

问题描述 投票:0回答:2

我正在开发一个项目,该项目使用 Hibernate 进行持久化,使用 Struts 2 进行视图模式。

我的配置文件是:

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>

我的问题是,我无法在 Struts 2 的视图模式中保持 Hibernate 会话打开,这意味着当我尝试加载一些尚未使用 Hibernate 初始化的数据(例如集合)时,我得到

org.hibernate.LazyInitializationException 
,所以在做了一些研究之后,我发现我必须在
web.xml
中添加这个范围,以保持会话在视图模式中打开。

范围:

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

但即使如此,我仍然遇到同样的问题,所以有人可以告诉我我做错了什么吗?

java spring hibernate struts2 open-session-in-view
2个回答
3
投票

过滤器链的顺序很重要。在您的情况下,会话应该在 struts 执行操作之前打开,并在之后关闭。最后一件事是由 Spring 通过管理 Hibernate 会话来完成的。因此,重新排序过滤器并允许 struts2 调度程序接受来自第一个过滤器的请求。

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

1
投票

我前段时间遇到过类似的问题,为了解决这个问题,我使用了 hibernate.enable_lazy_load_no_trans 属性而不是 OpenSessionInView 模式。有关 LazyInitializationException 的更多信息,您可以在 herehere

找到
© www.soinside.com 2019 - 2024. All rights reserved.