瞬时状态(Transient)
对象与session没有关联,数据库中没有对应的数据。
一般new
出来的对象便是瞬时对象。
对瞬时对象使用save()
方法便使之成为持久对象。
由于数据库中没有对应的数据,所以对瞬时对象使用update()
方法无效。
持久状态(Persistent)
对象与session有关联,且数据库中有对应id的数据。
使用get()
、load()
等方法获得的是持久对象。
对瞬时对象使用save()
方法便使之成为持久对象。
对游离对象使用update()
方法便使之成为持久对象。
对持久对象使用delete()
方法使使之成为瞬时对象。
游离状态(Detached)
对象与sessions没有关联,但数据库中有对应id的数据。
对瞬时对象使用setId()
方法,且数据库中有对应id的数据时,该对象便成为游离对象。
当对象为持久状态时,对session执行close()
、clear()
、evict()
等方法后,该持久对象变为游离对象。
对游离对象使用delete()
方法便使之成为瞬时对象。
对游离对象使用update()
方法便使之成为持久对象。
由于数据库中已经存在对应id的数据,所以对游离对象使用save()
方法无效。
saveOrUpdate()
另外,Hibernate提供了一个saveOrUpdate()
方法,Hibernate会根据对象的状态,选择正确的方式进行操作。具体说就是:当对象是瞬时状态时,执行save()
操作;当对象是游离状态时,执行update()
操作。在某些场景下,当不知道对象的具体状态时,可以考虑使用此方法。
merge()
当session中已经存在一个与持久对象关联的对象时(例如执行get()
、load()
等方法后),对一个持有相同id的游离对象进行update()
操作,这时session中便有2个相同id的对象,这是Hibernate所不允许的,因此会抛出异常。如果这时我们用merge()
方法代替update()
方法,Hibernate便会把游离对象的数据复制给session中的对象,而游离对象不会转化为持久对象,因此此时session中只有一个对象且数据已经更新,而游离对象还仍然是游离对象。