概述
问题起源于代码中对某个对象的处理逻辑,当发现该对象的某些属性变化时,先将原数据删除,再插入一个新对象,由于使用了Spring+Hibernate的组合,很容易写出如下代码:
1
2
3
4
5
6
7
8
9
|
//从数据库中读取原数据
Role entity = hibernateTemplate.load(ID);
//将数据复制到新对象上
Role newEntity =
new
Role();
BeanCopier.copy(entity, newEntity);
//删除原数据
hibernateTemplate.delete(entity);
//保存新数据
hibernateTemplate.save(entity);
|
1
2
|
SQL Error: 1062, SQLState: 23000
Duplicate entry
'demo'
for
key
'IDX_ROLE_NAME'
|
打开Hibernate的SQL输出,还原最真实的SQL语句,终于找到了答案,输入日志如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
Hibernate:
/* insert com.litt.cidp.system.po.Role
*/
insert
into
role
(ROLE_NAME, STATUS, REMARK)
values
(?, ?, ?)
Hibernate:
/* update
com.litt.cidp.system.po.Role */
update
role
set
ROLE_NAME=?,
STATUS=?,
REMARK=?
where
ROLE_ID=?
Hibernate:
/* delete com.litt.cidp.system.po.Role */
delete
from
role
where
ROLE_ID=?
|
Hibernate在最终执行SQL语句时,居然是按INSERT, UPDATE, DELETE的顺序执行的,而非按照代码顺序执行!What the F!查阅了相关资料,说是Hibernate为了性能优化,对象操作都是放在缓存里而没有立即执行数据库操作直到commit操作,为的是利用batch操作提高数据库操作性能;老天,那业务逻辑怎么办?同理,在一个事务中混用Hibernate和JDBC操作,将导致数据不一致问题。
解决方案:在需要同步的地方(即按照INSERT, UPDATE, DELETE顺序有可能产生问题的时候;混用JDBC操作的时候),执行session.flush()方案,该方法将缓存中的数据请求立即转换为数据库操作并执行。
最后
以上就是粗心玫瑰为你收集整理的Hibernate的SQL执行顺序引发的血案的全部内容,希望文章能够帮你解决Hibernate的SQL执行顺序引发的血案所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复