站在持久化的角度, Hibernate 把对象分为 4 种状态: 持久化状态, 临时状态, 游离状态, 删除状态. Session 的特定方法能使对象从一个状态转换到另一个状态.
–在使用代理主键的情况下, OID 通常为null–不处于 Session的缓存中–在数据库中没有对应的记录
–OID 不为null–位于 Session缓存中–若在数据库中已经有和其对应的记录,持久化对象和数据库中的相关记录对应–Session 在 flush缓存时,会根据持久化对象的属性变化, 来同步更新数据库–在同一个 Session实例的缓存中,数据库表中的每条记录只对应唯一的持久化对象
删除对象(Removed)
游离对象(也叫”脱管”) (Detached):
–在数据库中没有和其 OID 对应的记录–不再处于 Session缓存中–一般情况下, 应用程序不该再使用被删除的对象
OID 不为 null
不再处于 Session 缓存中
一般情况需下, 游离对象是由持久化对象转变过来的, 因此在数据库中可能还存在与它对应的记录
–当对一个 OID 不为Null的对象执行save()方法时,会把该对象以一个新的oid保存到数据库中; 但执行 persist()方法时会抛出一个异常.(在调用persist方法之前,若对象已经有id了,则不会执行insert,,而抛出一个异常)
1.无论要更新的游离对象和数据库的记录是否一致,都会发送update语句如何能让update方法不盲目的触发update语句呢?若希望 Session 仅当修改了 News 对象的属性时, 才执行 update() 语句, 可以把映射文件中 <class> 元素的 select-before-update 设为 true. 该属性的默认值为 false,但通常不需要设置该设置该属性(在update的情况下需要多发一条select语句)2.当 update() 方法关联一个游离对象时, 如果在数据库中不存在相应的记录, 也会抛出异常.3.当 update() 方法关联一个游离对象时, 如果在 Session 的缓存中已经存在相同 OID 的持久化对象, 会抛出异常。因为在session缓存中不能有两个oid相同的对象。
1.若OID不为null,但数据表中还没有和其对应的记录,会抛出一个异常2.了解:OID值等于id的unsaved-value属性的对象也被认为是一个游离对象
–触发器使Session的缓存中的持久化对象与数据库中对应的数据不一致:触发器运行在数据库中,它执行的操作对Session是透明的–Session的update()方法盲目地激发触发器:无论游离对象的属性是否发生变化,都会执行update语句,而update语句会激发数据库中相应的触发器
–在执行完Session的相关操作后,立即调用Session的flush()和refresh()方法,迫使Session的缓存与数据库同步(refresh()方法重新从数据库中加载对象)
-在映射文件的的 <class> 元素中设置 select-before-update 属性: 当 Session 的 update 或 saveOrUpdate() 方法更新一个游离对象时, 会先执行 Select 语句, 获得当前游离对象在数据库中的最新数据, 只有在不一致的情况下才会执行 update 语句
hibernate 持久化对象的状态,布布扣,bubuko.com
原文地址:http://blog.csdn.net/qilixiang012/article/details/27710133