Hibernate/Spring/Struts架构使用OpenSessionInView的问题

转载 2007年09月11日 18:36:00
 今天有一个朋友问了我一个问题,他使用的是Hibernate/Spring/Struts架构,配置使 用Spring的OpenSessionInView Filter,但是发现不生效,lazy的集合属性在页面访问的时候仍然报session已经关闭的错误。我和他一起检查了所有的配置和相关的代码,但是 没有发现任何问题。经过调试发现,应用程序使用的Session和OpenSessionInView Filter打开的Session不是同一个,所以OpenSessionInView模式没有生效,但是为什么他们不使用同一个Session呢?

检查了一遍Spring的相关源代码,发现了问题的根源:

通常在Web应用中初始化Spring的配置,我们会在web.xml里面配置一个Listener,即:

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对象里面保存:

java代码: 

servletContext.setAttribute( 
                                        WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, 
this .context);


请注意,保存的对象的key是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE!

但是ContextLoaderPlugIn初始化spring配置,然后把它放在ServletContext对象里面保存:

java代码: 


String attrName  =  getServletContextAttributeName(); 
getServletContext().setAttribute(attrName, wac);
这个attrName和WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE名字是不一样的!

如果仅仅是名字不一样,问题还不大,你仍然可以放心使用ContextLoaderPlugIn,但是当你使用OpenSessionInView的时候,OpenSessionInViewFilter是使用哪个key取得spring配置的呢?

java代码: 

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配置。

相关文章推荐

Spring3.x_Struts2.x_Hibernate3.x整合之OpenSessionInView的实现

由于Hibernate存在延迟加载的问题,当Dao的事物提交之后,session就关闭此时如果到显示层就没有办法获取对象,使用OpenSessionInViewer是解决延迟加载问题的方案。...
  • rzg813
  • rzg813
  • 2014年10月15日 22:40
  • 1331

Spring hibernate opensessioninview

  • 2008年01月24日 15:37
  • 1KB
  • 下载

使用Spring + Struts + Hibernate开发网站 -- 问题记录

我在大三实习的时候曾经在一家公司使用PHP开发网站,最近在另外一家公司实习,采用的语言是Java。虽然大学本科的时候学校做项目用java比较多,但是j2ee和android并没有学习多少。只是用Jav...

spring_struts1_hibernate架构空项目

  • 2013年03月10日 10:40
  • 17.69MB
  • 下载

struts+spring+hibernate是怎样的架构

举一个小例子回答楼主的问题。 加入我要盖一件小平房(做一个网站),我需要做的是: 1:买一块地。(租一台服务器)--1天 2:申请一个门牌号码(买一个域名)--1天 3:买材料,请2、3个工人,开始盖...

一种优雅的流行架构:Struts+Spring+Hibernate

用java来建立一个很有价值的web 应用不是一个简单的任务。在架构这个应用时要考虑很多的因素和问题。从更高的层次来看,开发人员面临着关于如何构建用户接口,何处驻留业务逻辑,以及如何实现数据持久性这些...

struts+spring+hibernate的web应用<一> 架构搭建

许久没有些文章了,现在比较清闲,于是决定用 struts+spring+hibernate 做了一个的小 web 应用。程序虽小,但五脏俱全,今后还会加上权限,打印等功能。   开发工具: ...

SSH架构(Struts+Spring+Hibernate)介绍和一个例子72

举一个小例子;加入我要盖一件小平房(做一个网站),我需要做的是;1:买一块地;2:申请一个门牌号码(买一个域名)--1天;3:买材料,请2、3个工人,开始盖房(准备所需要;4:盖房(敲代码编程)--1...
  • Alsyuan
  • Alsyuan
  • 2017年05月04日 09:03
  • 1008

struts2+hibernate+spring分页实现(DAO,Service,Action三层架构搭配)

Java代码  class=java name="code">       import java.util.List;       public interface Pa...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Hibernate/Spring/Struts架构使用OpenSessionInView的问题
举报原因:
原因补充:

(最多只允许输入30个字)