【问题标题】:Open Session in View pattern using Hibernate, Spring, Struts 2使用 Hibernate、Spring、Struts 2 在视图模式中打开会话
【发布时间】:2014-11-23 00:27:01
【问题描述】:

我正在开发一个项目,使用 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


    【解决方案1】:

    过滤器链的顺序很重要。在您的情况下,会话应该在 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>
    

    【讨论】:

    • 感谢您的回答,我完全按照您所说的做了,但现在我收到另一条错误消息:“没有定义名为 'sessionFactory' 的 bean”
    • 如果您按照我说的做,您将无法收到此消息。如果此消息是在您执行我所说的任何操作之前出现的,那么最好提出一个新问题。
    • 你没有告诉我我必须把这个 contextConfigLocationclasspath:applicationContext.xmlvalue> org.springframework.web.context.ContextLoaderListener听众>我认为这个错误来自哪里
    • 不,没有告诉你,因为你没有问过我。你想知道它应该在哪里吗?
    • 我的回答只与您的问题中的一个问题有关,如果您有其他问题,您应该单独询问,或者您的问题过于宽泛。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2010-12-23
      • 1970-01-01
      • 2013-06-05
      • 1970-01-01
      • 2011-06-13
      • 2015-01-03
      • 2011-03-10
      • 1970-01-01
      • 2022-01-24
      相关资源
      最近更新 更多