HIbernate的delete save

在网上资料说,hibernate有它自己的优化机制,你所有的操作都会在hibernate的SQL队列里面,这个队列就是先处理Insert,然后再处理Delete。执行顺序和我们写的顺序无关。

如果你要保证先执行Delete操作,那么你需要再delete操作后执行flush()操作,提交事务。然后再执行insert()操作。

我原来一开始这样子写的:

commonService.delete(CaseDetail.class,oldCaseDetail.getId());

commonService.save(caseDetail);

前提:casedetail表的case_sequence_number是唯一键

报错:

Duplicate entry 'XM102020042210481' for key 'idx_caseDetail_case_sequence_number'

oldCaseDetail和caseDetail拥有相同的caseNo值为XM102020042210481,

caseNo在数据库里面是唯一约束,索引名字idx_caseDetail_case_sequence_number。

 

我在想,上面说的应该是delete,insert 等操作是在同一个事务里面,如果不在同一个事务里面的话,那么这样子写

commonService.delete(CaseDetail.class,oldCaseDetail.getId());

commonService.save(caseDetail);

应该是不会报错的,个人觉得,不是同一事务的话,hibernate是不会把sql存在一个sql队列里面的,都是来一个执行一个,做下实验呢:

我把两个操作不放在事务里面执行:

实验结果:当执行到

commonService.delete(Payback.class,1);的时候,数据库的数据就直接被删除了,当然啦,后面的数据是可以正常保存的。

 

然后再做一个实验:把这两个操作放在同一个事务里面。

实验结果:

当执行到

commonService.delete(Payback.class,1);的时候,数据库的数据还存在,并没有直接删除,因为在事务里面,事务还没有提交。

当执行后面保存代码的时候,就报错了:

 

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------

怎么解决这个问题呢?

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------

方案一:就像上面第一个例子,不放在同一个事务,就不会存在这种情况。

方案二在事务里面,执行了delete操作后,就flush()方法提交sql  【建议】

commit()方法里面有调用到session.flush()方法。flush会把sql执行,打印出来,但是这个时候数据库数据不会变,需要commmit后数据才更改。也就是flush()只是提交sql不执行事务。

 

 

实验结果:

是可以正常保存后面的数据的。

关于flush的解读:

 

 

方案三:如果项目使用到了spring  JdbcTemplate的话,可以删除操作使用 jdbctemplate来,因为他不是hibernate的操作,所有不会被那个在SQL操作里面排队,所以就不存在hiberante的规则--》先insert再删除。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值