Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushM

org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.
在插入数据方法正确的情况下,更新和删除方法出了这个错,错误显示是StudentDaoHibernateTest里的testUpdate方法除了错

问题原因分析:

1、为了解决session closed 错误而是用 openSessionInViewInterceptor 或者 openSessionInViewFilter 延迟加载的错误,但是在我们开启OpenSessionInViewFilter这个过滤器的时候FlushMode就已经被默认设置为了MANUAL,如果FlushMode是MANUAL或NEVEL,在操作过程中 hibernate会将事务设置为readonly,所以在增加、删除或修改操作过程中会出现如下错误
 

2、Hibernate框架中sql语句是通过配置自动生成的,方法执行不正确说明很可能是SQL语句生成不正确或者没有配置生成修改和删除sql语句的事务,配置spring 事务,让spring 来管理hibernate session,有 aop, 有基于注解的;(本人推荐这种方式,因为项目都会有事务的操作)查看hibernate.xml发现如下:

<!-- Spring 会根据 tx:advice 中的配置动态产生 相应的事务控制代码  -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="persist*" read-only="false" propagation="REQUIRED" isolation="READ_COMMITTED" />
        <tx:method name="find*" read-only="true" propagation="REQUIRED" isolation="READ_COMMITTED" />
    </tx:attributes>
</tx:advice>

发现没有配置修改和删除的事务控制代码,配置如下:

 

注意:为了解决问题原因1,配置read-only="false" 即关闭它的只读属性,

99.9%的人配置了事务之后,都会解决这个问题。但是还有0.1%的会报实体类属性为空的错误。

第一,检查事务的传播级别对不对,

例如 你配的

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

但是你的方法名称是 delInfo(...)..;那么你对应的事务传播级别就是 <tx:method name="*" read-only="true" /> ;还是read-only;

所以你要给你的方法改为 deleteInfo(...);或者在事务的传播级别加上一个<tx:method name="del*" propagation="REQUIRED" />


isolation="READ_COMMITTED"表示事务的隔离级别为(读已提交) —— 事务可以读取由另一事务提交的数据。

 

3、还有一点就是update执行的时候要先查到再重新赋值后再执行更新,代码如下:

public @Test void testUpdate(){
    Student s=studentDao.find(5);
    s.setName("山谷百合");
    s.setGender("女");
    calendar.set(1998,9,8);
    java.util.Date birthdate=calendar.getTime();
    s.setBirthdate(birthdate);
    studentDao.update(s);
    System.out.println("更新成功!");
}

public @Test void testRemove(){
    studentDao.remove(5);
    System.out.println("删除成功");
}
 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值