`
simgsg
  • 浏览: 96051 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Spring+Hibernate中的(FlushMode.NEVER)错误产生及解决

 
阅读更多
<p>Spring+Hibernate中的(FlushMode.NEVER)错误产生及解决<br><a href="http://www.firnow.com">www.firnow.com</a> 时间 : 2007-10-18 作者:佚名 编辑:本站 点击: 1597 [ 评论 ]<br>-<br>-</p>
<p>在没有使用Spring提供的Open Session In View情况下,因需要在service(or Dao)层里把session关闭,所以lazy loading 为true的话,要</p>
<p>在应用层内把关系集合都初始化,如 company.getEmployees(),否则Hibernate抛session already closed Exception; Open Session In </p>
<p>View提供了一种简便的方法,较好地解决了lazy loading问题.</p>
<p> 它有两种配置方式OpenSessionInViewInterceptor和OpenSessionInViewFilter(具体参看SpringSide),功能相同,只是一个在web.xml配</p>
<p>置,另一个在application.xml配置而已。</p>
<p> Open Session In View在request把session绑定到当前thread期间一直保持hibernate session在open状态,使session在request的整个期</p>
<p>间都可以使用,如在View层里PO也可以lazy loading数据,如 ${ company.employees }。当View 层逻辑完成后,才会通过Filter的doFilter</p>
<p>方法或Interceptor的postHandle方法自动关闭session。</p>
<p></p>
<p>OpenSessionInViewInterceptor配置&lt;beans&gt; <br>&lt;bean name="openSessionInViewInterceptor" class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor"&gt; </p>
<p><br>&lt;property name="sessionFactory"&gt; <br>&lt;ref bean="sessionFactory"/&gt; <br>&lt;/property&gt; <br>&lt;/bean&gt; <br>&lt;bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"&gt; <br>&lt;property name="interceptors"&gt; <br>&lt;list&gt; <br>&lt;ref bean="openSessionInViewInterceptor"/&gt; <br>&lt;/list&gt; <br>&lt;/property&gt; <br>&lt;property name="mappings"&gt; <br>... <br>&lt;/property&gt; <br>&lt;/bean&gt; <br>... <br>&lt;/beans&gt; <br>OpenSessionInViewFilter配置<br>&lt;web-app&gt;<br>... <br>&lt;filter&gt; <br>&lt;filter-name&gt;hibernateFilter&lt;/filter-name&gt; <br>&lt;filter-class&gt; <br>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter <br>&lt;/filter-class&gt; <br>&lt;!-- singleSession默认为true,若设为false则等于没用OpenSessionInView --&gt; <br>&lt;init-param&gt; <br>&lt;param-name&gt;singleSession&lt;/param-name&gt; <br>&lt;param-value&gt;true&lt;/param-value&gt; <br>&lt;/init-param&gt; <br>&lt;/filter&gt; <br>... <br>&lt;filter-mapping&gt; <br>&lt;filter-name&gt;hibernateFilter&lt;/filter-name&gt; <br>&lt;url-pattern&gt;*.do&lt;/url-pattern&gt; <br>&lt;/filter-mapping&gt;<br>... <br>&lt;/web-app&gt; <br>很多人在使用OpenSessionInView过程中提及一个错误:</p>
<p>org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode </p>
<p>(FlushMode.NEVER) - turn your Session into FlushMode.AUTO or remove 'readOnly' marker from transaction definition 看看</p>
<p>OpenSessionInViewFilter里的几个方法</p>
<p>protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,FilterChain filterChain) throws </p>
<p>ServletException, IOException <br>{ <br>SessionFactory sessionFactory = lookupSessionFactory(); <br>logger.debug("Opening Hibernate Session in OpenSessionInViewFilter"); <br>Session session = getSession(sessionFactory); <br>TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session)); <br>try<br>{  filterChain.doFilter(request, response); <br>} <br>finally <br>{ <br>TransactionSynchronizationManager.unbindResource(sessionFactory); logger.debug("Closing Hibernate Session in </p>
<p>OpenSessionInViewFilter"); <br>closeSession(session, sessionFactory); <br>}<br>} <br>protected Session getSession(SessionFactory sessionFactory)throws DataAccessResourceFailureException <br>{ <br>Session session = SessionFactoryUtils.getSession(sessionFactory, true); <br>session.setFlushMode(FlushMode.NEVER); <br>return session;<br>}<br>protected void closeSession(Session session, SessionFactory sessionFactory)throws CleanupFailureDataAccessException<br>{ <br>SessionFactoryUtils.closeSessionIfNecessary(session, sessionFactory);<br>} <br>可以看到OpenSessionInViewFilter在getSession的时候,会把获取回来的session的flush mode 设为FlushMode.NEVER。<br>然后把该sessionFactory绑定到TransactionSynchronizationManager,使request的整个过程都使用同一个session,<br>在请求过后再接除该sessionFactory的绑定,最后closeSessionIfNecessary根据该session是否已和transaction绑定来决定是否关闭session</p>
<p>。在这个过程中,若HibernateTemplate 发现自当前session有不是readOnly的transaction,就会获取到FlushMode.AUTO Session,使方法拥</p>
<p>有写权限。</p>
<p>public static void closeSessionIfNecessary(Session session, SessionFactory sessionFactory) throws </p>
<p>CleanupFailureDataAccessException <br>{ <br>if (session == null || TransactionSynchronizationManager.hasResource(sessionFactory)) { <br>return; <br>} <br>logger.debug("Closing Hibernate session"); <br>try { <br>session.close(); <br>} <br>catch (<br>JDBCException ex) <br>{ <br>// SQLException underneath <br>throw new CleanupFailureDataAccessException("Could not close Hibernate session", ex.getSQLException()); <br>} <br>catch (HibernateException ex) <br>{ <br>throw new CleanupFailureDataAccessException("Could not close Hibernate session", ex); <br>} <br>} <br>也即是,如果有不是readOnly的transaction就可以由Flush.NEVER转为Flush.AUTO,拥有insert,update,delete操作权限,如果没有</p>
<p>transaction,并且没有另外人为地设flush model的话,则doFilter的整个过程都是Flush.NEVER。所以受transaction保护的方法有写权限,</p>
<p>没受保护的则没有。</p>
<p>采用spring的事务声明,使方法受transaction控制 <br>&lt;bean id="baseTransaction" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" </p>
<p>abstract="true"&gt; <br>&lt;property name="transactionManager" ref="transactionManager"/&gt; <br>&lt;property name="proxyTargetClass" value="true"/&gt; <br>&lt;property name="transactionAttributes"&gt; <br>&lt;props&gt; <br>&lt;prop key="get*"&gt;<br>PROPAGATION_REQUIRED,readOnly<br>&lt;/prop&gt; <br>&lt;prop key="find*"&gt;<br>PROPAGATION_REQUIRED,readOnly<br>&lt;/prop&gt; </p>
<p>&lt;prop key="load*"&gt;PROPAGATION_REQUIRED,readOnly<br>&lt;/prop&gt; <br>&lt;prop key="save*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt; <br>&lt;prop key="add*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt; <br>&lt;prop key="update*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt; <br>&lt;prop key="remove*"&gt;PROPAGATIO</p>
<p><br>Spring+Hibernate中的(FlushMode.NEVER)错误产生及解决<br><a href="http://www.firnow.com">www.firnow.com</a> 时间 : 2007-10-18 作者:佚名 编辑:本站 点击: 1598 [ 评论 ]<br>-<br>-<br>N_REQUIRED&lt;/prop&gt; <br>&lt;/props&gt; <br>&lt;/property&gt; <br>&lt;/bean&gt; <br>&lt;bean id="userService" parent="baseTransaction"&gt; <br>&lt;property name="target"&gt; <br>&lt;bean class="com.phopesoft.security.service.impl.UserServiceImpl"/&gt; <br>&lt;/property&gt; <br>&lt;/bean&gt; <br>对于上例,则以save,add,update,remove开头的方法拥有可写的事务,如果当前有某个方法,如命名为importExcel(),则因没有transaction</p>
<p>而没有写权限,这时若方法内有insert,update,delete操作的话,则需要手动设置flush model为Flush.AUTO,如<br>session.setFlushMode(FlushMode.AUTO); <br>session.save(user); <br>session.flush(); <br>尽管Open Session In View看起来还不错,其实副作用不少。看回上面OpenSessionInViewFilter的doFilterInternal方法代码,这个方法实际</p>
<p>上是被父类的doFilter调用的,因此,我们可以大约了解的OpenSessionInViewFilter调用流程: request(请求)-&gt;open session并开始</p>
<p>transaction-&gt;controller-&gt;View(Jsp)-&gt;结束transaction并close session.<br>一切看起来很正确,尤其是在本地开发测试的时候没出现问题,但试想下如果流程中的某一步被阻塞的话,那在这期间connection就一直被占</p>
<p>用而不释放。最有可能被阻塞的就是在写Jsp这步,一方面可能是页面内容大,response.write的时间长,另一方面可能是网速慢,服务器与用</p>
<p>户间传输时间久。当大量这样的情况出现时,就有连接池连接不足,造成页面假死现象。</p>
<p>Open Session In View是个双刃剑,放在公网上内容多流量大的网站请慎用 </p>
<p><br><a href="http://www.firnow.com):http://dev.firnow.com/course/3_program/java/javajs/20071018/77920.html"></a></p>
分享到:
评论

相关推荐

    hibernate错误解决方案

    通过上述对几个常见 Hibernate 错误的解析及解决方法的介绍,我们可以发现大部分问题都与配置文件的设置、实体类的定义以及事务管理有关。在日常开发中,我们应该注意这些细节,以避免不必要的错误发生。同时,对于...

    struts2.3+spring3.1.2+hibernate4.1.6 配置说明

    Struts2、Spring和Hibernate是Java开发中的三大框架,它们的集成能够构建出强大的企业级应用。在这个配置说明中,开发者使用的是Struts2.3、Spring3.1.2和Hibernate4.1.6的版本。 首先,我们需要了解这三大框架的...

    Struts1.x Spring2.x Hibernate3.x DWR2.x整合工具文档v1.00

    为了提高性能,通常会在Spring中使用`OpenSessionInViewFilter`来管理Hibernate的Session。这样可以在整个请求周期内保持Session打开状态,从而避免多次打开和关闭Session带来的性能损失。 ```xml &lt;filter-name&gt;...

    使用Spring引起的错误

    ### 使用Spring引起的错误:Write operations are not allowed in read-only mode (FlushMode.NEVER) #### 问题背景 在使用Spring框架时,特别是在与Hibernate结合的情况下,可能会遇到“Write operations are not...

    hibernate二级缓存

    例如,`FlushMode.NEVER`表示从不自动刷新,`FlushMode.AUTO`则会在某些操作后自动刷新。 在工程示例中,`FlushMode.doc`可能详细介绍了各种FlushMode的使用场景和效果,而`2级缓存.doc`应该包含了二级缓存的配置和...

    如何解决hibernate自动更新实体类的问题共5页.pd

    4. **控制Flush模式**:可以设置`Session`的flush模式,如`FlushMode.NEVER`表示永不flush,`FlushMode.MANUAL`表示手动flush。但请注意,过度使用可能会导致数据一致性问题。 5. **显式调用update()或saveOrUpdate...

    Open_Session_In_View详解.doc

    #### 四、常见问题及解决办法 在使用`Open Session In View`时,可能会遇到一些问题,其中最常见的是以下错误: ```java org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not ...

    HIbernate Session 详解

    #### 一、Session在Hibernate中的地位及作用 在Hibernate框架中,`Session` 是一个非常核心且重要的组件。作为Hibernate提供的主要操作数据库的接口,`Session` 不仅承担着保存、更新、删除数据的任务,还负责执行...

    hibernate中文参考手册

    在Java开发中,Hibernate提供了一种抽象层,允许开发者使用面向对象的编程方式来操作数据库,而无需直接编写SQL语句,极大地提高了开发效率。 本手册《Hibernate中文参考手册》详细介绍了Hibernate的核心概念、配置...

    Hibernate3.5官方开发文档pdf + html

    Hibernate 3.5是Java开发中的一个非常重要的对象关系映射(ORM)框架,它极大地简化了数据库操作,使得开发者可以使用面向对象的方式来处理数据库事务。这个官方开发文档包括PDF和HTML两种格式,为开发者提供了详尽...

    spring_demo:Spring MVC示范项目

    Spring MVC Hibernate Demo Hibernate 配置 数据库实体必须设置以下注解 @Entity ... &lt;filter&gt;org.springframework.orm.hibernate4.support.OpenSessionInViewFilter &lt;param&gt;flushMode&lt;/param-nam

    HIBERNATE FOR NETBEANS 数据操作方法

    下面将详细介绍如何在NetBeans中配置Hibernate以及使用它进行数据操作。 1. **安装Hibernate插件** - 首先,确保你已经安装了NetBeans IDE的最新版本。在这个例子中,我们提及的是NetBeans 5.x,但请确保你使用的...

    hibernate简单实例

    在开始任何操作之前,你需要在项目中引入Hibernate的核心库,包括hibernate-core.jar和其他相关依赖。通常,这些依赖可以通过Maven或Gradle等构建工具管理。同时,确保JDBC驱动也在类路径中,以便连接到数据库。 2...

    Hibernate中文教程

    通过本教程的学习,读者能够深入了解Hibernate的工作原理和使用方法,掌握其核心特性和高级功能,从而能够在实际项目中有效地利用Hibernate解决复杂的数据持久化问题。此外,本教程还提供了丰富的实战案例和常见问题...

    hibernate学习总结

    在Java世界中,Hibernate 提供了一种在对象模型和关系数据库之间进行转换的机制,使得开发人员可以使用面向对象的方式来处理数据库操作,而无需直接编写SQL语句。 ### 1. Hibernate核心概念 - **实体(Entity)**:...

    Hibernate中Criteria的使用

    Hibernate 中 Criteria 的使用 Hibernate 中 Criteria 的使用是 Hibernate 框架中的一种查询机制,对于研究 Hibernate 源码有一些作用。在查询方法设计上可以灵活地根据 Criteria 的特点来方便地进行查询条件的组装...

    Hibernate中Criteria的完整用法

    本文详细介绍了Hibernate中`Criteria`的使用方法及应用场景。`Criteria`作为Hibernate提供的一种强大的查询工具,能够满足大多数场景下的需求,并且提供了丰富的API支持。通过对`Criteria`的深入了解和掌握,可以...

    Hibernate_demo

    《深入理解Hibernate5:基于Hibernate_demo的实践指南》 Hibernate作为一个强大的对象关系映射(ORM)框架,一直以来都是Java开发者的重要工具。本文将基于提供的"Hibernate_demo"项目,深入探讨Hibernate5的核心...

    Hibernate_api

    - Spring框架集成:Spring提供了对Hibernate的支持,简化了配置和事务管理。 - JPA集成:Hibernate作为JPA的实现,可以使用JPA规范进行开发。 总结,Hibernate API 是Java开发者处理数据库的强大工具,它简化了...

Global site tag (gtag.js) - Google Analytics