hibernate对象三种状态及其转换
·瞬时状态(transient):
刚用new语句创建,还没有被持久化,不处于Session的缓存中。处于瞬态的Java对象称为瞬态对象。
瞬态对象(TransientObjects):使用new操作符初始化的对象不是立刻就持久化的。它们的状态是瞬时的,也就是说他们没有任何跟数据库表相关联的行为,只要应用不再引用这些对象(不再被任何其他对象所引用),它们的状态将会丢失,并由垃圾回收机制回收。
瞬态对象具有以下特征:
(1)不处于Session的缓存中,也可以说,不被任何一个Session实例关联。
(2)在数据库中没有对应的记录。
在以下情况下,Java对象进入瞬态:
(1)当通过new语句刚创建了一个Java对象,它处于瞬态,此时不和数据库中的任何记录对应。
(2)Session的delete()方法能使一个持久化对象或脱管对象转变为瞬态对象。对于脱管对象,delete()方法从数据库中删除与它对应的记录;对于持久化对象,delete()方法从数据库中删除与它对应的记录,并且把它从Session的缓存中删除。
·持久化状态(persistent):
已经被持久化,加入到Session的缓存中。处于持久化状态的Java对象称为持久化对象。
持久化对象(PersistObjects):持久实例是任何具有数据库标识的实例。它有持久化管理器Session统一管理,持久实例是在事务中进行操作的———他们的状态在事务结束时同数据库进行同步。当事务提交时,通过执行SQL的INSERT,UPDATE和DELETE语句把内存中的状态同步到数据库中。
持久化对象具有以下特征:
(1)位于一个Session实例的缓存中,也可以说,持久化对象总是被一个Session实例关联。
(2)持久化对象和数据库中的相关记录对应。
(3)Session在清理缓存时,会根据持久化对象的属性变化,来同步更新数据库。
Session的许多方法都能够触发Java对象进入持久化状态:
(1)Session的save()方法把瞬态对象转变为持久化对象。
(2)Session的load()或get()方法返回的对象总是处于持久化状态。
(3)Session的find()方法返回的List集合中存放的都是持久化对象。
(4)Session的update()、saveOrUpdate()和lock()方法使脱管对象转变为持久化对象。
(5)当一个持久化对象关联一个瞬态对象,在允许级联保存的情况下,Session在清理缓存时会把这个瞬态对象也转变为持久化对象。
·脱管状态(detached):
已经被持久化,但不再处于Session的缓存中。处于脱管状态的Java对象称为脱管对象。
脱管对象(DetachedObjects):Session关闭之后,持久化对象就变为脱管对象。脱管表示这个对象不能再与数据库保持同步,他们不再受Hibernate管理。
脱管对象的特征。脱管对象具有以下特征:
(1)不再位于Session的缓存中,也可以说,脱管对象不被Session关联。
(2)脱管对象是由持久化对象转变过来的,因此在数据库中可能还存在与它对应的记录(前提条件是没有其他程序删除了这条记录)。
脱管对象与瞬态对象的相同之处在于,两者都不被Session关联,因此Hibernate不会保证它们的属性变化与数据库保持同步。
脱管对象与瞬态对象的区别在于:前者是由持久化对象转变过来的,因此可能在数据库中还存在对应的记录,而后者在数据库中没有对应的记录。
Session的以下方法使持久化对象转变为脱管对象:
(1)当调用Session的close()方法时,Session的缓存被清空,缓存中的所有持久化对象都变为脱管对象。如果在应用程序中没有引用变量引用这些脱管对象,它们就会结束生命周期。
(2)Session的evict()方法能够从缓存中删除一个持久化对象,使它变为脱管状态。当Session的缓存中保存了大量的持久化对象,会消耗许多内存空间,为了提高性能,可以考虑调用evict()方法,从缓存中删除一些持久化对象。