简体   繁体   English

Hibernate,Spring,Struts2:以视图模式打开会话

[英]Hibernate, Spring, Struts2: Open Session in View pattern


I'm working on a project using Hibernate for persisting and Struts2 for the view pattern. 我正在使用Hibernate进行持久化而使用Struts2作为视图模式的项目。 my configuration files are: 我的配置文件是:

web.xml web.xml

 <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 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 probleme is I can't keep Hibernate session open in the view pattern of Struts2, 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. 我的问题是我无法在Struts2的视图模式下保持Hibernate会话打开,这意味着当我尝试加载一些尚未使用Hibernate初始化的数据时(例如,像集合),我得到了org.hibernate.LazyInitializationException ,因此通过进行一些研究,我发现必须在web.xml中添加此范围,以使会话在视图模式下保持打开状态。

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. 但是即使这样我仍然有同样的问题,所以谁能告诉我我在做什么错。

The order of filter chain is important. 过滤器链的顺序很重要。 In your case the session should be opened before struts is executing actions and closed after that. 在您的情况下,应在Struts执行动作之前打开会话,然后在Strut执行动作之前关闭会话。 The last thing is done by spring via managing Hibernate session. 最后一件事是在春季通过管理Hibernate会话完成。 So, reorder filters and allow struts2 dispatcher accept requests from the first filter. 因此,对过滤器重新排序,并允许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>

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. 我前段时间遇到过类似的问题,为了解决此问题,我使用了hibernate.enable_lazy_load_no_trans属性而不是OpenSessionInView模式。 More informations about LazyInitializationException you can find here or here 有关LazyInitializationException的更多信息,请在此处此处找到

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM