Hibernate中的对象状态
在Hibernate中对象分成三种状态:Transient(瞬时/自由),Persistent(持久), Detached(脱管/游离),其中处于Transient和Detached态的Obejct都可以算作Value Object。
一般瞬时对象都是通过new出来的,只用于数据存储、传递,经过save、persist等方法使之与数据库相关联,此时转换为持久对象。
持久对象存有一个数据库标识,因此对它进行操作时,数据库中的值也会对应改变。在结束会话时或delete时持久对象将转换为脱管对象。
脱管对象和瞬时对象一样,也只用于数据存储、传递,但是比它多了一个数据库标识(经过了持久态而携带)。如果它是因为delete产生,可以由save、saveOrUpdate等方法重新变为持久对象;如果它是由于会话结束而脱管,可以通过lock、update、replicate等方法重新变为持久对象。
脱管对象和瞬时对象在无法被引用到时都会被JVM回收。
附几个方法的比较:
·save与update:save存储一个新的对象(瞬时-持久),update更新原来对象的值到数据库,此时对象应该要有一个标识,因此是(脱管-持久)。
·update与saveOrUpdate:saveOrUpdate包括了save和update。在saveOrUpdate时,如果对象是瞬时态,则对其save,如果对象是脱管态,则调用update,如果是持久态,则不做任何事(但注意,如果不是自己sessoin的持久态对象,与本session中另一个持久态对象含有同一个标识的话将抛出异常)。
·persist与save:都是将瞬时对象转换为持久态,但是persist时并不马上填入标识,可能在flush时才给对象一个标识,而save是立即执行。
·update与merge:都是将脱管状态转换为持久态,但是update时如果脱管态与本session中的另一PO有相同标识,会抛出异常;如果是merge,此时会将脱管态的属性赋值到那个PO,执行后脱管态还是脱管态,PO还是PO。。。
·flush与update:update操作脱管态-持久态,flush操作持久态。一般PO都会被hibernate自动调用flush,在此之前并不会立即更新到数据库中,而是存在session的缓存里,因此有时需要手工flush强制更新。
·lock与update:update针对改过的脱管态-持久态;lock负责未改过的脱管态对象转换为持久态(只负责session关闭造成的脱管态对象)。
·clear与evcit:clear清除整个session的缓存,evcit只删除session中的单个对象。