我正在开发一个项目,使用Hibernate进行持久化,使用Struts2进行视图模式。
我的配置文件是:
的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
<?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>
我的问题是我无法在Struts2的视图模式中保持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>
但即便如此,我仍然有同样的问题,所以有人能告诉我我做错了什么。
答案 0 :(得分:3)
过滤器链的顺序很重要。在您的情况下,会话应该在struts执行操作之前打开,之后关闭。最后一件事是通过管理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 :(得分:1)