浅谈hibernate save和saveOrUpdate区别
Hibernate对象的状态
Hibernate的对象有3种状态,分别为:瞬时态(Transient)、持久态(Persistent)、脱管态(Detached)。处于持久态的对象也称为PO(Persistence Object),瞬时对象和脱管对象也称为VO(Value Object)。
save和saveOrUpdate的区别
save
是保存要持久化的数据,会走insert语句。saveOrUpdate
根据unsaved-value的设定,判定是要save还是update操作。
遇到的问题及解决方案
在项目中,我在service层中的一个函数中对一个实体batch进行一次save
然后进行数据处理,最后又调用了一次update
方法用于更新batch的状态。即添加时状态为“0”,数据处理后更新状态为“1”。此时出现 a different object with the same identifier value was already associated with the session
异常。
分析后认为,update
时数据需为PO(Persistence Object),但save
后batch变为了VO(Value Object)状态,导致此异常。后来在update
前先get一下batch然后更新是没问题的,但是这样有导致多走了一次select语句。
因为batch与数据库是一直的(因为刚刚save
),所以就想如何让其insert后仍然处于PO状态。后来看到资料使用了saveOrUpdate
方法,测试后发现,没有问题,不再出异常,所以认为 save
和 saveOrUpdate
除了在运行机制上有区别以外,在 insert
以后:
save
后的实体处于VO(Value Object)状态。- 通过
saveOrUpdate
后的实体 处于PO(Persistence Object)状态。
可以修改实体后直接调用 update
方法,执行更新操作。