通过Spring的OpenSessionInViewFilter管理Hibernate的Session来解决LazyLoad(延时加载)的问题

原文链接: https://blog.csdn.net/wuseyukui/article/details/16113785

1、什么是OpenSessionInView

在hibernate中使用load方法时,并未把数据真正获取时就关闭了session,当我们真正想获取数据时会迫使load加载数据,而此时session已关闭,所以就会出现异常。 比较典型的是在MVC模式中,我们在M层调用持久层获取数据时(持久层用的是load方法加载数据),当这一调用结束时,session随之关闭,而我们希望在V层使用这些数据,这时才会迫使load加载数据,我们就希望这时的session是open着得,这就是所谓的Open Session In view 。 我们可以用filter来达到此目的。 这段话引至于百度百科,但确实很好的说明了OpenSessionInView这个过滤器的作用。

OpenSessionInViewFilter是Spring提供的一个针对Hibernate的一个支持类,其主要意思是在发起一个页面请求时打开Hibernate的Session,一直保持这个Session,直到这个请求结束,具体是通过一个Filter来实现的。  由于Hibernate引入了Lazy Load特性,使得脱离Hibernate的Session周期的对象如果再想通过getter方法取到其关联对象的值,Hibernate会抛出一个LazyLoad的Exception。所以为了解决这个问题,Spring引入了这个Filter,使得Hibernate的Session的生命周期变长。  

2、解决方法

在JavaWeb项目的 web.xml  配置文件中加上以下配置信息。



    openSessionInViewFilter
    org.springframework.orm.hibernate5.support.OpenSessionInViewFilter
    
        singleSession
        false
    


    openSessionInViewFilter
    /*

在上面配置中我们要注意以下几点:

1、这个filter一定要配置在struts的过滤器的前面,因为过滤器是“先进后出”原则,如果你配置在struts的后面的话,你的openSessionInView过滤器都执行完了,怎么在去在管理action的转向页面啊。

2、Opensessioninview也需要sessionfactory的bean的注入,他默认的去找bean的id为sessionfactory的bean,如果sessionfactory的bean的id不是这个名字的话,要记得给这个过滤器配置一个参数,参数名为sessionfactoryBeanName,把他的value设置为你的sessionfactory的bean的id值。

3、在用opensessioninview的时候一定要注意,如果你不配置transaction的话,在用opensessioninview时,他默认的把事务配置为only-read只读,这样的话,如果你进行增删改的时候,他就会报一个在只读事务中不能进行增删改的操作。如果把opensessioninview去掉,他默认的事务的开始边界就锁定在dao层操作上,dao层hibernatetempt提供了事务的开始和提交。

3、OpenSessionInView的副作用

了解了上面几个问题之后,那么也就可以大概知道OpenSessionInView的副作用 – 资源占用严重,配置不当,影响系统性能。使用OpenSessionInView后,在request发出和response返回的流程中,如果有任何一步被阻塞,那在这期间connection就会被一直占用而不释放。比如页面较大,显示需要时间 或者 网速太慢,服务器与用户间传输的时间太长,这都会导致资源占用,最直接的表现就是连接池连接不够用,而导致最终服务器无法提供服务。

原文地址:Spring之OpenSessionInView详解及用法

学习资料:通过Spring管理hibernate session来解决lazy-load的问题

你可能感兴趣的:(Spring,Java,EE)