Hibernate session FlushMode

Hibernate session FlushMode有五种属性:

1、NEVEL:已经废弃了,被MANUAL取代了

2 MANUAL:

如果FlushMode是MANUAL或NEVEL,在操作过程中hibernate会将事务设置为readonly,所以在增加、删除或修改操作过程中会出现如下错误

org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER) - turn your Session into FlushMode.AUTO or remove ‘readOnly‘ marker from transaction definition;

解决办法:配置事务,spring会读取事务中的各种配置来覆盖hibernate的session中的FlushMode;

3 AUTO

设置成auto之后,当程序进行查询、提交事务或者调用session.flush()的时候,都会使缓存和数据库进行同步,也就是刷新数据库

4 COMMIT

提交事务或者session.flush()时,刷新数据库;查询不刷新

5 ALWAYS:

每次进行查询、提交事务、session.flush()的时候都会刷数据库

ALWAYS和AUTO的区别:当hibernate缓存中的对象被改动之后,会被标记为脏数据(即与数据库不同步了)。当 session设置为FlushMode.AUTO时,hibernate在进行查询的时候会判断缓存中的数据是否为脏数据,是则刷数据库,不是则不刷,而always是直接刷新,不进行任何判断。很显然auto比always要高效得多。

参见hibernate的api说明https://www.hibernate.org/hib_docs/v3/api/org/hibernate/FlushMode.html

(二)

spring 环境下做一个check*操作时,抛出异常

org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are

not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into

FlushMode.COMMIT/AUTO or remove ‘readOnly‘ marker from transaction definition.

后来发现,由于我在Action中调的方法名是checkXXXXX打头,而我的applicationContext.xml中的相关配置如下:

Xml代码 

  1. <bean id="transactionInterceptor"
  2. class="org.springframework.transaction.interceptor.TransactionInterceptor">
  3. <property name="transactionManager" ref="transactionManager" />
  4. <property name="transactionAttributes">
  5. <props>
  6. <prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>
  7. <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
  8. <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
  9. <prop key="view*">PROPAGATION_REQUIRED,readOnly</prop>
  10. <prop key="merge*">PROPAGATION_REQUIRED,readOnly</prop>
  11. <prop key="check*">PROPAGATION_REQUIRED,readOnly</prop>
  12. <prop key="insert*">
  13. PROPAGATION_REQUIRED,-GenericException
  14. </prop>

Xml代码  

  1. <bean id="transactionInterceptor"
  2. class="org.springframework.transaction.interceptor.TransactionInterceptor">
  3. <property name="transactionManager" ref="transactionManager" />
  4. <property name="transactionAttributes">
  5. <props>
  6. <prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>
  7. <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
  8. <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
  9. <prop key="view*">PROPAGATION_REQUIRED,readOnly</prop>
  10. <prop key="merge*">PROPAGATION_REQUIRED,readOnly</prop>
  11. <prop key="check*">PROPAGATION_REQUIRED,readOnly</prop>
  12. <prop key="insert*">
  13. PROPAGATION_REQUIRED,-GenericException
  14. </prop>

即check打头的操作时,是不可操作数据库的,包括更新与增加数据。

找到原因后将

Xml代码 

  1. <prop key="check*">PROPAGATION_REQUIRED,readOnly</prop>

Xml代码  

  1. <prop key="check*">PROPAGATION_REQUIRED,readOnly</prop>

改为

Xml代码 

  1. <prop key="check*">PROPAGATION_REQUIRED</prop>

Xml代码  

  1. <prop key="check*">PROPAGATION_REQUIRED</prop>

后,重启服务,问题解决。

(三)

<aop:config proxy-target-class="true">

<aop:pointcut id="managerOperation" expression="execution(* com.yyii.eip..service.*Manager.*(..))"/>

<aop:advisor advice-ref="txAdvice" pointcut-ref="managerOperation"/>

</aop:config>

<!-- 基本事务定义 -->

<tx:advice id="txAdvice" transaction-manager="transactionManager">

<tx:attributes>

<tx:method name="save*"/>

<tx:method name="update*"/>

<tx:method name="remove*"/>

<tx:method name="delete*"/>

<tx:method name="create*"/>

<!-- other methods are set to read only -->

<tx:method name="*" read-only="true"/>

</tx:attributes>

</tx:advice>

如果把proxy-target-class="true"去掉, 不会报warn

但如果写上proxy-target-class="true", 2.0的配置依然会报WARN

修改web.xml中的]<param-value>false</param-value>为false试试!

<filter>

<filter-name>hibernateFilter</filter-name>

<filter-class>

org.springframework.orm.hibernate3.support.OpenSessionInViewFilter

</filter-class>

<init-param>

<param-name>singleSession</param-name>

<param-value>false</param-value> </init-param>

</filter>

<!-- 配置事务特性 -->

<tx:advice id="txAdvice" transaction-manager="transactionManager">

<tx:attributes>

<tx:method name="add*" propagation="REQUIRED"/>

<tx:method name="del*" propagation="REQUIRED"/>

<tx:method name="update*" propagation="REQUIRED"/>

<tx:method name="*" read-only="true"/>

</tx:attributes>

</tx:advice>

<!-- 配置那些类的方法进行事务管理 -->

<aop:config>

<aop:pointcut id="allManagerMethod" expression="execution (* com.landa.oa.manager.*.*(..))"/>

<aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod"/>

</aop:config>

<!--End_rbody_54519835//-->

Exceptions:

org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove ‘readOnly‘ marker from transaction definition.

at org.springframework.orm.hibernate3.HibernateTemplate.checkWriteOperationAllowed(HibernateTemplate.java:1112)

at org.springframework.orm.hibernate3.HibernateTemplate$14.doInHibernate(HibernateTemplate.java:663)

时间: 2024-11-03 20:48:31

Hibernate session FlushMode的相关文章

spring管理hibernate session的问题探究

我们再用spring管理hibernate的时候, 我们会继承HibernateDaoSupport 或者HibernateTemplate类. 我们不知道这两个类之间有什么关系. 也没有去关闭session. 让我很是心不安,他可没有关闭session呀.如果..真的是后果不堪设想.百度了好久, 谷歌了好多. 都没有一个像样的说法. 说spring中HibernateDaoSupport会自己关闭session. 眼见为实.于是乎决定查看spring源码一探究竟. 先打开HibernateDa

Hibernate Session &amp; Transaction详解

Hibernate Session & Transaction详解 HIbernate中的Session Session是JAVA应用程序和Hibernate进行交互时使用的主要接口,它也是持久化操作核心API, 注意这里的Session的含义,它与传统意思上web层的HttpSession并没有关系,Hibernate Session之与Hibernate,相当于JDBC Connection相对与JDBC. Session对象是有生命周期的,它以Transaction对象的事务开始和结束边界

hibernate session.get(class,serialid) 方法为空值的原因?

package hibernate.test; import hibernate.test.pojo.Person; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; impo

hibernate session问题大总结

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

Hibernage错误:Could not open Hibernate Session for transaction

今天在做SSH框架整合的时候碰到的这个问题,在测试service层的时候程序正常运行,但是添加Struts,在action层测试的时候提示了如下问题:Could not open Hibernate Session for transaction.大概意思就是数据库连接超时. 解决方法如下: 在spring的配置文件中添加如下配置 给sessionFactory的bean添加如下配置 <bean id="sessionFactory" class="org.spring

hibernate session.save()和session.persist()的区别

save()需要返回一个Serialzable的实现类,因此执行这个方法时会马上插入到数据库 而persist()不会立即插入到数据库. "当我们封装一个长会话流程的时候,persist()方法就显得尤为重要了!" 记录下来,防止自己再一次忘记 hibernate session.save()和session.persist()的区别,码迷,mamicode.com

org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not

遇到这个问题之前,我去百度和谷歌去搜索了一下,发现各种说法,但是针对我的项目而言,也就是公司的项目而言,这个问题的根源并非是网上所说的那样. 最后是通过自己的想法做测试得到了解决. 1.首先说说我的配置吧!我的配置是通过spring自带的注解来实现 声明式事物管理的.如果我们没去了解spring的声明式事物管理的话,或许我们是得不出什么结论的. 如果你配置过声明式事物管理,你就知道spring是怎么帮你管理的. 2.spring声明式事物管理是在service层管理的,关于到sessionFac

第二节 hibernate session基本方法介绍

Hibernate session 对象是和数据库建立连接的对象,session中包含了许多操作数据库的方法,下面一一描述. 1 保存对象到数据库 session.save(); 按照第一节的配置,主键的生成策略为native(数据库自动生成主键),由于数据库使用的是mysql 5,所以是自增的主键生成方式.保存对象时并不需要设置id属性. @Test public void testSave() { try { User user = new User(); user.setBirthday(

spring 管理事务配置时,结果 报错: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here这个异常

java.lang.IllegalStateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here这个异常 这个错误,网上说的原因一大推,反正我这个出的问题 是因为 虽然我在 spring 里把事务都配置好了,结果运行就出现这个错误,看看配置都没什么问题,都是网上 案例 照 写编码的,还是错的,结果发现是因为 我