Spring学习(五)OpenSessionInView

转载 2017年01月03日 11:59:32

首先我们来看一下什么是OpenSessionInView?


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

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


首先分析一下它的源码,可以发现,它所实现的功能其实比较简单:

    SessionFactory sessionFactory = lookupSessionFactory(request);  
    Session session = null;  
    boolean participate = false;  
      
    if (isSingleSession()) {  
        // single session mode  
        if (TransactionSynchronizationManager.hasResource(sessionFactory)) {  
        // Do not modify the Session: just set the participate flag.  
        participate = true;  
           }    else {  
        logger.debug("Opening single Hibernate Session in OpenSessionInViewFilter");  
        session = getSession(sessionFactory);  
        TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));  
        }  
    } else {  
        // deferred close mode  
        if (SessionFactoryUtils.isDeferredCloseActive(sessionFactory)) {  
    // Do not modify deferred close: just set the participate flag.  
        participate = true;  
        } else {  
        SessionFactoryUtils.initDeferredClose(sessionFactory);  
        }  
    }  
      
    try {  
        filterChain.doFilter(request, response);  
    } finally {  
        if (!participate) {  
                if (isSingleSession()) {  
                    // single session mode  
            TransactionSynchronizationManager.unbindResource(sessionFactory);  
            logger.debug("Closing single Hibernate Session in OpenSessionInViewFilter");  
            closeSession(session, sessionFactory);  
        }else {  
            // deferred close mode  
            SessionFactoryUtils.processDeferredClose(sessionFactory);  
        }  
    }  
    }  

在上述代码中,首先获得SessionFactory,然后通过SessionFactory获得一个Session。然后执行真正的Action代码,最后根据情况将HibernateSession进行关闭。整个思路比较清晰。  


下面我们来看一下他的具体配置,其实很简单,直接在web.xmlfilter配置

    <filter>  
    <filter-name>openSessionInView</filter-name>  
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>  
    <init-param>  
    <param-name>sessionFactoryBeanName</param-name>  
    <param-value>sf</param-value>  
    </init-param>  
    </filter>  
    <filter-mapping>  
    <filter-name>openSessionInView</filter-name>  
    <url-pattern>/*</url-pattern>  
    </filter-mapping>  

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

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

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

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

OpenSessionInView的副作用

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

Spring hibernate opensessioninview

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

(OpenSessionInView模式)spring对session和事务的管理以及OpenSessionInViewFilter是如何工作的

为了弄清楚spring对session和事务的管理以及OpenSessionInViewFilter是如何工作的,可监控以下类的日志:   org.springframework.orm.hiber...

spring--openSessionInView的使用步骤

OpenSessionInView 在显示层打开session    由于hibernate存在延迟加载的问题,当dao的事物提交之后,session就关闭  此时显示层 view JSP界面需...

java框架spring中的opensessioninview有什么作用

在hibernate中使用load方法时,并未把数据真正获取就关闭了session,当真正想获取数据时会迫使load加载数据,而此时session已关闭,所以就会出现异常。 比较典型的是在MVC模式中...

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

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

Java程序员从笨鸟到菜鸟之(八十三)细谈Spring(十二)OpenSessionInView详解及用法

首先我们来看一下什么是OpenSessionInView?     在hibernate中使用load方法时,并未把数据真正获取时就关闭了session,当我们真正想获取数据时会迫使load...

详细解析Spring事务的配置和OpenSessionInview的作用

1.事务的特性   原子性:事务中的操作是不可分割的一部分   一致性:要么同时成功,要么同时失败(事务执行前后数据保持一致)   隔离性:并发互不干扰     持久性:事务一旦被提交,它就是...
  • JacXuan
  • JacXuan
  • 2017年02月16日 13:26
  • 4175

spring OpenSessionInView

参考文献: http://blog.csdn.net/wuseyukui/article/details/16113785 http://justsee.iteye.com/blog/1174999 ...

Spring之OpenSessionInView详解及用法

首先我们来看一下什么是OpenSessionInView?     在hibernate中使用load方法时,并未把数据真正获取时就关闭了session,当我们真正想获取数据时会迫使...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Spring学习(五)OpenSessionInView
举报原因:
原因补充:

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