这篇文章给大家介绍 hibernate 中对象的状态有哪三种,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
一,首先 hibernate 中对象的状态有三种:瞬态、游离态和持久态,三种状态转化的方法都是通过 session 来调用,瞬态到持久态的方法有 save()、saveOrUpdate()、get()、load();持久态到瞬态的方法有 delete();游离态到持久态的方法有 update()、saveOrUpdate()、lock();持久态到游离态的方法有:session.close()、session.evict()、session.clear()。
二,Hibernate 的状态
hibernate 的各种保存方式的区 (save,persist,update,saveOrUpdte,merge,flush,lock) 及 对象的三种状态
hibernate 的保存
hibernate 对于对象的保存提供了太多的方法,他们之间有很多不同,这里细说一下,以便区别。
一、预备知识
在所有之前,说明一下,对于 hibernate,它的对象有三种状态,transient、persistent、detached
下边是常见的翻译办法:
transient:瞬时态或者临时态
(new DeptPo(1,”行政部”,20,”行政相关”),该 po 的实例和 session 没有关联,该 po 的实例处于 transient)
persistent:持久化状态
(和数据库中记录想影射的 Po 实例,它的状态是 persistent, 通过 get 和 load 等得到的对象都是 persistent)
detached:脱管状态或者游离态
(1)当通过 get 或 load 方法得到的 po 对象它们都处于 persistent, 但如果执行 delete(po)时 (但不能执行事务), 该 po 状态就处于 detached, (表示和 session 脱离关联), 因 delete 而变成游离态可以通过 save 或 saveOrUpdate() 变成持久态
(2)当把 session 关闭时,session 缓存中的 persistent 的 po 对象也变成 detached
因关闭 session 而变成游离态的可以通过 lock、save、update 变成持久态
持久态实例可以通过调用 delete()变成脱管状态。
通过 get()或 load()方法得到的实例都是持久化状态的。
脱管状态的实例可以通过调用 lock()或者 replicate()进行持久化。
save()和 persist()将会引发 SQL 的 INSERT,delete()会引发 SQLDELETE,
而 update()或 merge()会引发 SQL UPDATE。对持久化 (persistent) 实例的修改在刷新提交的时候会被检测到,它也会引起 SQL UPDATE。
saveOrUpdate()或者 replicate()会引发 SQLINSERT 或者 UPDATE
二、save 和 update 区别
把这一对放在第一位的原因是因为这一对是最常用的。
save 的作用是把一个新的对象保存
update 是把一个脱管状态的对象或自由态对象 (一定要和一个记录对应) 更新到数据库
三、update 和 saveOrUpdate 区别
这个是比较好理解的,顾名思义,saveOrUpdate 基本上就是合成了 save 和 update, 而 update 只是 update; 引用 hibernate reference 中的一段话来解释他们的使用场合和区别
通常下面的场景会使用 update()或 saveOrUpdate():
程序在第一个 session 中加载对象, 接着把 session 关闭
该对象被传递到表现层
对象发生了一些改动
该对象被返回到业务逻辑层最终到持久层
程序创建第二 session 调用第二个 session 的 update()方法持久这些改动
saveOrUpdate(po)做下面的事:
如果该 po 对象已经在本 session 中持久化了,在本 session 中执行 saveOrUpdate 不做任何事
如果 savaOrUpdate(新 po)与另一个与本 session 关联的 po 对象拥有相同的持久化标识(identifier),抛出一个异常
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [org.itfuture.www.po.Xtyhb#5]
saveOrUpdate 如果对象没有持久化标识 (identifier) 属性,对其调用 save(),否则 update() 这个对象
四、persist 和 save 区别
这个是最迷离的一对,表面上看起来使用哪个都行,在 hibernate reference 文档中也没有明确的区分他们.
这里给出一个明确的区分。(可以跟进 src 看一下,虽然实现步骤类似,但是还是有细微的差别)
主要内容区别:
1,persist 把一个瞬态的实例持久化,但是并 不保证 标识符 (identifier 主键对应的属性) 被立刻填入到持久化实例中,标识符的填入可能被推迟到 flush 的时候。
2,save, 把一个瞬态的实例持久化标识符,及时的产生, 它要返回标识符,所以它会立即执行 Sql insert
五、saveOrUpdate,merge 和 update 区别
比较 update 和 merge
update 的作用上边说了,这里说一下 merge 的
如果 session 中存在相同持久化标识 (identifier) 的实例,用用户给出的对象覆盖 session 已有的持久实例
(1)当我们使用 update 的时候,执行完成后,会抛出异常
(2)但当我们使用 merge 的时候,把处理自由态的 po 对象 A 的属性 copy 到 session 当中处于持久态的 po 的属性中,执行完成后原来是持久状态还是持久态,而我们提供的 A 还是自由态
六、flush 和 update 区别
这两个的区别好理解
update 操作的是在自由态或脱管状态 (因 session 的关闭而处于脱管状态) 的对象 //updateSQL
而 flush 是操作的在持久状态的对象。
默认情况下,一个持久状态的对象的改动 (包含 set 容器) 是不需要 update 的,只要你更改了对象的值,等待 hibernate flush 就自动更新或保存到数据库了。hibernate flush 发生在以下几种情况中:
1,调用某些查询的和手动 flush(),session 的关闭、SessionFactory 关闭结合
get()一个对象,把对象的属性进行改变, 把资源关闭。
2,transaction commit 的时候(包含了 flush)
七、lock 和 update 区别
update 是把一个已经更改过的脱管状态的对象变成持久状态
lock 是把一个没有更改过的脱管状态的对象变成持久状态(针对的是因 Session 的关闭而处于脱管状态的 po 对象(2),不能针对因 delete 而处于脱管状态的 po 对象)
对应更改一个记录的内容,两个的操作不同:
update 的操作步骤是:
(1)属性改动后的脱管的对象的修改 - 调用 update
lock 的操作步骤是:
(2)调用 lock 把未修改的对象从脱管状态变成持久状态 – 更改持久状态的对象的内容 – 等待 flush 或者手动 flush
八、clear 和 evcit 的区别
clear 完整的清除 session 缓存
evcit(obj)把某个持久化对象从 session 的缓存中清空。
session.lock(xtyhb,LockMode.NONE);// 表示直接到缓存中去找变成持久态的对象
session.lock(xtyhb,LockMode.READ);// 先通过 ID 读数据库该记录的 ID 看是否有该记录,如果有接着到缓存中去找变成持久态的对象
在 Hibernate 中,对象有三种状态:临时状态、持久状态和游离状态。
也叫:瞬时态(Transient)、持久态(Persistent)、脱管态(Detached)。处于持久态的对象也称为 PO(Persistence Object),瞬时对象和脱管对象也称为 VO(Value Object)。
临 时状态:当 new 一个实体对象后,这个对象处于临时状态,即这个对象只是一个保存临时数据的内存区域,如果没有变量引用这个对象,则会被 jre 垃圾回收机 制回收。这个对象所保存的数据与数据库没有任何关系,除非通过 Session 的 save 或者 SaveOrUpdate 把临时对象与数据库关联,并把数据插 入或者更新到数据库,这个对象才转换为持久对象。
例如:Emp e=new Emp(); // 创建临时对象
e.setEmpno((long) 8888);
e.setEName(mike
…
EmpDAO d=new EmpDAO();
d.save(e); // 持久化
…
持久状态: 持久化对象的实例在数据库中有对应的记录,并拥有一个持久化表示(ID)。对持久化对象进行 delete 操作后,数据库中对应的记录将被删除,那么持久化对象与数据库记录不再存在对应关系,持久化对象变成临时状态。
持久化对象被修改变更后,不会马上同步到数据库,知道数据库事务提交。在同步之前,持久化对象是脏的(Dirty)。
例如:
Emp e=new Emp(); // 创建了临时的对象
EmpDAO edao= new empDAO();
e=edao.findbyEmpno((long) 7786); // 使对象与数据库记录对应,从而持久化
e.setEname(新的名字 // 修改了持久化对象,使之处于 Dirty
……
edao.saveorupdate(e); // 保存,但是仍然 Dirty
tran.commit(); // 提交,实现与数据库同步,不再 Dirty
……
游离状态:当 Session 进行了 Close、Clear 或者 evict 后,持久化对象虽然拥有持久化标识符和与数据库对应记录一致的值,但是因为 会话已经消失,对象不在持久化管理之内,所以处于游离状态(也叫:脱管状态)。游离状态的对象与临时状态对象是十分相似的,只是它还含有持久化标识。
瞬时态
由 new 命令开辟内存空间的 java 对象,
eg. Person person = new Person(xxx , xx
如果没有变量对该对象进行引用,它将被 java 虚拟机回收。
瞬时对象在内存孤立存在,它是携带信息的载体,不和数据库的数据有任何关联关系,在 Hibernate 中,可通过 session 的 save()或 saveOrUpdate()方法将瞬时对象与数据库相关联,并将数据对应的插入数据库中,此时该瞬时对象转变成持久化对象。
持久态
处于该状态的对象在数据库中具有对应的记录,并拥有一个持久化标识。如果是用 hibernate 的 delete()方法,对应的持久对象就变成瞬时对象,因数据库中的对应数据已被删除,该对象不再与数据库的记录关联。
当一个 session 执行 close()或 clear()、evict()之后,持久对象变成脱管对象,此时持久对象会变成脱管对象,此时该对象虽然具有数据库识别值,但它已不在 HIbernate 持久层的管理之下。
持久对象具有如下特点:
1. 和 session 实例关联;
2. 在数据库中有与之关联的记录。
脱管态
当与某持久对象关联的 session 被关闭后,该持久对象转变为脱管对象。当脱管对象被重新关联到 session 上时,并再次转变成持久对象。
脱管对象拥有数据库的识别值,可通过 update()、saveOrUpdate()等方法,转变成持久对象。
脱管对象具有如下特点:
1. 本质上与瞬时对象相同,在没有任何变量引用它时,JVM 会在适当的时候将它回收;
2. 比瞬时对象多了一个数据库记录标识值。
关于 hibernate 中对象的状态有哪三种 就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。