OpenSessionInViewFilter的配置

在项目中时常会碰见对关联表数据的操作。例如用户与角色表、角色与资源表等等,在建立这些表对应得实体时,默认采用的懒加载机制(fetch=FetchType.LAZY)及只有在需要的时候才会查询对应得关联表数据。但是在spring管理的hibernate一次请求的session默认在Service层有效。离开Service层当前请求的session就关闭了。若我们想在jsp页面得到关联表对应的数据就会报no session错。

为了实现这一需求主要两种方案:

1、在建立关联实体对象时关闭懒加载功能。及设置fetch=FetchType.EAGER

2、需要在web.xml中配置OpenSessionInViewFilter过滤器。

Spring 为我们提供了一个叫做 OpenSessionInViewFilter 的过滤器,他是标准的 Servlet Filter 所以我们把它按照规范配置到 web.xml 中方可使用。使用中我们必须配合使用 Spring 的 HibernateDaoSupport 来进行开发,也就是说,我们的dao层的类都要继承于 HibernateDaoSupport,从中由 Spring 来控制 Hibernate 的 Session 在请求来的时候开启,走的时候关闭,保证了我们访问数据对象时的稳定性。

    <!-- 配置OpenSessionInViewFilter 保证session在一次请求完成后才关闭 -->
     <filter>
    	<filter-name>openSessionInViewFilter</filter-name>
    	<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
    	<init-param>
    	<!-- singleSession默认为true,若设为false则等于没用OpenSessionInView 。所以默认可以不写 -->
    		<param-name>singleSession</param-name>
    		<param-value>true</param-value>
    	</init-param>
    	<init-param>
	    	<!-- 
	    	指定org.springframework.orm.hibernate3.LocalSessionFactoryBean在spring配置文件中的名称,默认值为sessionFactory。
	    	 如果LocalSessionFactoryBean在spring中的名称不是sessionFactory,该参数一定要指定,否则会出现找不到sessionFactory的例外。所以默认可以不写
	    	 -->
    		<param-name>sessionFactoryBeanName</param-name>
    		<param-value>sessionFactory</param-value>
    	</init-param>
    	<init-param>
	    	<!-- 
	    	在项目中使用Spring+Hibernate的时候,会开启OpenSessionInViewFilter来阻止延迟加载的错误,
	    	但是在我们开启OpenSessionInViewFilter这个过滤器的时候FlushMode就已经被默认设置为了MANUAL,如果FlushMode是MANUAL或NEVEL,
	    	在操作过程中 hibernate会将事务设置为readonly,若要进行增加、删除或修改操作则需要手动设置flushMode为AUTO
	    	-->
    		<param-name>flushMode</param-name>     
 			<param-value>AUTO</param-value>
    	</init-param>
    </filter>
    
    <filter-mapping>
    	<filter-name>openSessionInViewFilter</filter-name>
    	<url-pattern>/*</url-pattern>
    	<dispatcher>REQUEST</dispatcher>
    	<dispatcher>FORWARD</dispatcher>
    </filter-mapping> 


OpenSessionInViewFilter的主要功能是用来把一个Hibernate Session和一次完整的请求过程对应的线程相绑定。Open Session In View在request把session绑定到当前thread期间一直保持hibernate session在open状态,使session在request的整个期间都可以使用,如在View层里PO也可以lazy loading数据,如 ${ company.employees }。当View 层逻辑完成后,才会通过Filter的doFilter方法或Interceptor的postHandle方法自动关闭session。


由于使用了OpenSessionInView模式后造成了内存和数据库连接问题 
  这个问题是我在生产环境中碰到的一个问题。由于使用了OpenSessionInView模式,Session的生命周期变得非常长。虽然解决了Lazy Load的问题,但是带来的问题就是Hibernate的一级缓存,也就是Session级别的缓存的生命周期会变得非常长,那么如果你在你的Service层做大批量的数据操作时,其实这些数据会在缓存中保留一份,这是非常耗费内存的。还有一个数据库连接的问题,存在的原因在于由于数据库的Connection是和Session绑在一起的,所以,Connection也会得不到及时的释放。因而当系统出现业务非常繁忙,而计算量又非常大的时候,往往数据连接池的连接数会不够。这个问题我至今非常头痛,因为有很多客户对数据连接池的数量会有限制,不会给你无限制的增加下去。

http://www.cnblogs.com/children/archive/2010/05/01/1725419.html

OpenSessionInViewFilter作用及配置:http://www.yybean.com/opensessioninviewfilter-role-and-configuration

OpenSessionInView详解:http://www.javaeye.com/topic/32001

http://schnauzer.iteye.com/blog/160024



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值