最近在使用Hibernate,读了读《Hibernate3和JPA程序开发——从入门到精通》这本书,发现其中的有些章节内容写的很好,在这里把自己认为是精华的东西整理出来,既是自勉,同时与大家分享一下。这一篇关注持久化对象中的各种状态的转换规则。
1、关于持久化对象的状态
Hibernate中的持久化对象可能处于如下几种状态下:
- 暂态:对象刚创建,与数据库记录没有关联。
- 持久态:对象与数据库中记录同步,并且数据变更处于Session的管理之下。
- 游离态:对象脱离Session的管理,无法与数据库中的记录保持同步。
- 移除态:对象已经被Session删除,但操作还没有提交给数据库。
上图为Hibernate中的实体对象状态及其相互间的转换关系。
2、关于Session
Hibernate的核心类是Session,它是Hibernate进行持久化操作的工作单元,可以管理持久化对象,完成对各实体对象的基本持久化操作。
Session中提供了如下操作实体对象的方法:
- 获取对象。session.get和session.load。二者的主要区别是:get方法始终返回对象的实例,而load方法除非在持久化上下文中已经存在一个该标识符定位的对象,不然总是先返回对象的代理。此外,在无法找到指定数据库记录时,get方法返回null,而load方法抛出ObjectNotFoundException。
- 保存对象。session.save和session.persist。二者的主要区别是:save方法返回对象的标识符,而persist方法无返回值。此外,persist方法只能保存暂态和持久态的对象,而save方法可以保存任何状态的对象。
- 更新对象。session.update。此外,方法session.saveOrUpdate方法提供了便捷的编码方式,使用户无须关心持久化对象的状态,可以优先使用。
- 合并对象。session.merge。把游离态对象复制到工作单元中,然后将游离态的内容更新到数据库中。
- 删除对象。session.delete。被删除后的对象处于移除态,直到它的标识符被清空时,才进入暂态。
Session对各种状态实体对象进行操作的可能结果如下表所示。
对象状态 | save | update | saveOrUpdate | persist | merge | delete |
暂态 | ok | 抛出StateException,暂态对象不可更新 | ok | ok | 识别出暂态对象并保存 | 不作任何操作 |
持久态 | 等同于update | 如果对象发生变化,则更新记录 | 如果对象发生变化,则更新记录 | 等同于update | 等同于update | 删除数据库记录 |
游离态 | 将游离态对象作为暂态对象保存,保存后的对象获得一个新的标识符 | 如果对象发生变化,则更新记录 | 如果对象发生变化,则更新记录 | 抛出Persistent--ObjectException | 确保当前持久化上下文中存在一个拥有同样标识符同样类型的对象,将游离态对象的属性复制到该持久态对象,之后更新数据库记录。合并完成后,游离态对象不会被置于持久化上下文内 | 删除数据库记录 |
移除态 | 将移除态对象作为暂态对象保存,保存后的对象获得一个新的标识符 | 抛出StateException,删除的对象不可更新 | 将移除态对象作为暂态对象保存,保存后的对象获得一个新的标识符 | 抛出Persistent-ObjectException | 移除态的对象含有标识符,合并后该对象会被以同样的标识符保存在数据库中。 | 抛出StateException,已删除对象不可再次删除 |
3、Session操作与持久化对象状态转移的关系
如下图所示,下图给出了持久对象状态转换与Session操作的关系。