配置使用Spring的OpenSessionInView Filter,发现不生效,lazy的集合属性在页面访问的时候仍然报session已经关闭的错误。经过调试发现,应用程序使用的Session和OpenSessionInView Filter打开的Session不是同一个,所以OpenSessionInView模式没有生效,但是为什么他们不使用同一个Session呢?
检查了一遍Spring的相关源代码,发现了问题的根源:
通常在Web应用中初始化Spring的配置,我们会在web.xml里面配置一个Listener,即:
listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
如果使用Struts,那么需要在Struts的配置文件struts-config.xml里面配置一个Spring的plugin:ContextLoaderPlugIn。
实际上ContextLoaderListener和ContextLoaderPlugIn的功能是重叠的,他们都是进行Spring配置的初始化工作的。因此,如果你不打算使用OpenSessionInView,那么你并不需要在web.xml里面配置ContextLoaderListener。
好了,但是你现在既需要Struts集成Spring,又需要OpenSessionInView模式,问题就来了!
由于ContextLoaderListener和ContextLoaderPlugIn功能重叠,都是初始化Spring,你不应该进行两次初始化,所以你不应该同时使用这两者,只能选择一个,因为你现在需要集成Struts,所以你只能使用ContextLoaderPlugIn。
但是令人困惑的是,ContextLoaderListener和ContextLoaderPlugIn有一个非常矛盾的地方!
ContextLoaderListener初始化spring配置,然后把它放在ServletContext对象里面保存:
请注意,保存的对象的key是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE!
但是ContextLoaderPlugIn初始化spring配置,然后把它放在ServletContext对象里面保存:
String attrName = getServletContextAttributeName();;
getServletContext();.setAttribute(attrName, wac);;
这个attrName和WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE名字是不一样的!
如果仅仅是名字不一样,问题还不大,你仍然可以放心使用ContextLoaderPlugIn,但是当你使用OpenSessionInView的时候,OpenSessionInViewFilter是使用哪个key取得spring配置的呢?
WebApplicationContext wac =
WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext(););;
显然,OpenSessionInViewFilter是按照WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE这个key去拿spring配置的!
整理一下思路:
ContextLoaderPlugIn保存spring配置的名字叫做attrName;
,ContextLoaderListener保存spring配置的名字叫做WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE;
而OpenSessionInView是按照WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE这个名字去取得spring配置的!
而你的应用程序却是按照attrName去取得spring的配置的!
所以,OpenSessionInView模式失效!
解决办法:
修改ContextLoaderPlugIn代码,在getServletContext().setAttribute(attrName, wac);这个地方加上一行代码:
getServletContext().setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
或者修改OpenSessionInViewFilter,让它按照attrName去取得spring配置。
具体可参考:
http://www.iteye.com/topic/15057?page=1
分享到:
相关推荐
使用OpenSessionInView可以避免此类问题。 **局限性**: - **性能问题**:由于Session保持打开状态的时间较长,可能会导致更多的数据库连接占用,影响系统性能。 - **异常处理**:如果没有正确处理异常,可能导致...
为了练手培训,给大家准备的 Open...3.通过 open session in view filter 支持 延迟加载 4.在页面上通过 jstl 很优雅的获取数据 5.通过 spring aop(aspectJ) 声明事务 6.通过formular 映射参数表,指定两个死的变量
在Java Web开发中,OpenSessionInView(OSIV)模式是一种常见的解决数据持久化问题的设计模式,主要用于Spring框架与Hibernate等ORM工具的集成。这个模式的主要目的是解决在HTTP请求处理过程中,由于Session范围内的...
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> <param-name>singleSession <param-value>true </filter> <filter-mapping> <filter-name>...
在处理Web应用时,Spring提供了一些关键特性,如`CharacterEncodingFilter`和`OpenSessionInViewFilter`,它们对于解决特定问题至关重要。 首先,让我们深入了解一下`CharacterEncodingFilter`。在Web应用中,字符...
同时,需要注意的是,OpenSessionInView模式虽然方便,但也会带来潜在的问题,如事务边界不清晰和会话泄漏。因此,在实际应用中,应结合具体需求谨慎使用,并考虑使用更现代的解决方案,如Spring Data JPA的...
和Spring中OpenSessionInView由于org.springframework.web.struts.ContextLoaderPlugIn中保存同一个对象的名不同导致openSessionInView失效 稍微修改后在struts-config.xml中使用MyContextLoaderPlugIn.jar包中...
OpenSessionInView(OSIV)模式是SSH整合中常见的一种优化策略,它在用户的一次HTTP请求过程中保持Hibernate Session,避免了多次打开和关闭Session,减少了N+1查询问题,提高了性能。 **Spring** 是一个全面的企业...
为了解决这个问题,Spring提供了一个过滤器 `OpenSessionInViewFilter` 或者 `OpenSessionInViewInterceptor`,通常简称为OSIV(Open Session In View)模式。 OSIV模式的核心思想是在Controller层和View层之间保持...
<filter-name>openSessionInView</filter-name> <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>...
<filter-name>openSessionInView</filter-name> <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class> <param-name>sessionFactoryBeanName <param-value>...
<filter-name>openSessionInView</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> <!--...--> </filter> ``` 此过滤器保持一个打开的Hibernate ...
2. **OpenSessionInView模式**: 为了防止Session在请求结束后关闭导致数据丢失,我们可以使用`OpenSessionInViewFilter`。这个过滤器在每次请求开始时打开Session,结束时关闭,保证在整个视图渲染过程中Session都是...
- **字符编码过滤器**:用于确保所有的请求和响应都使用UTF-8编码,避免中文乱码问题。 - **Hibernate OpenSessionInView过滤器**:开启Hibernate的事务管理功能,确保在一个HTTP请求处理过程中始终有一个打开的...
### SSH框架搭建详解 #### 一、概述 SSH框架指的是Struts2、Spring以及Hibernate三个技术的集成。本文将详细地介绍如何从零开始搭建一...需要注意的是,在实际开发过程中,还需要关注异常处理、日志记录等细节问题。
OpenSessionInViewFilter是Spring框架中一个非常重要的组件,主要用于解决数据访问层(DAO)与视图层(View)之间的事务管理问题。在Web应用中,由于HTTP请求的无状态性,一次请求通常由多个Servlet过滤器、控制器和...
3,在web.xml中配置 spring 的 OpenSessionInView 过滤器(解决抛LazyInitializationException的问题) 1,配置 <!-- 配置 spring 的 OpenSessionInView 过滤器 --> <filter> <filter-name>...
5. **OpenSessionInView模式** - 修改`HibernateSessionFactory.java`,实现线程局部变量存储事务对象。 - 实现`beginTransaction`、`commitTransaction`、`rollbackTransaction`等方法,确保在每次请求结束时关闭...
- **OpenSessionInView**: 通过Web层的Filter在一次请求周期内保持Session打开,确保所有延迟加载的属性能在Session关闭前完成加载。 #### 八、Spring事务管理 **问题:** Spring支持几种事务管理方式?事务的隔离...
-- Hibernate OpenSessionInView 过滤器 --> <filter> <filter-name>OpenSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>...