使用JPA查询到的对象属性被set后,自动执行update语句,更新数据库

Spring data JPA查询到的对象被set值后,自动更新数据库

做项目开发的时候遇到这样一个问题:数据库有临时表和正式表,数据审批通过后才会进入正式表,根据业务要求,页面的数据需要通过临时表对象来显示,当需要显示正式表数据时,先查询到临时表对象,再查询正式表对象,将正式表对象赋值给临时表对象用于页面显示,代码执行完毕后,发现数据库正式表数据覆盖了临时表数据,很纳闷,查看代码,在把正式表数据赋值给临时表对象后,并没有保存临时表对象的代码呀,数据库怎么会被更新?
后来查看日志发现,当将正式表数据赋值给临时表时,有一条update语句执行了。查看资料后才知道,使用JPA查询后的对象处于持久态,持久态的对象属性在被set后,会自动执行update语句更新数据库。
这才恍然大悟,基于这个原因,只要把持久态的对象转换为游离态或者是临时态,就可以解决问题。
先理解下Hibernate 中对象的三种状态:
(1)临时状态:通过new新建的对象,没有被持久化,也不在session缓存中
(2)游离状态:已经被持久化,但不在session缓存中
(3)持久状态:已经被持久化,也在session缓存中
(持久化:数据库有这条数据)
持久态到游离态的方法有:session.close()、session.evict(obj)、session.clear()
close():关闭session,整个session中的持久态对象都成为游离态
clear():清楚session中的所有缓存,所有持久化对象变为游离态
evict(obj):把某个持久化状态的对象从session中清除,该对象变为游离态

根据三个方法的介绍,最好的处理方式应该选择evict(obj)方法。

由于业务需求,我的解决方式是,新建一个临时态的临时表对象,将查询到的正式表对象赋值给临时态对象,这样就不会触发update语句,经测试,问题解决。

出现这种现象的前提,查询以及对查询后的实体set值都必须在一个事务里,并且在方法执行结束,事务提交前,不管有没有显示调用update,JPA都会自动调用update.

你可能感兴趣的:(使用JPA查询到的对象属性被set后,自动执行update语句,更新数据库)