[转]Hibernate Session各种状态转换方法分析

时间:2023-02-23 08:04:42

摘自http://spiritfrog.iteye.com/blog/221177

我的印象里, Hibernate session中常用的保存操作只有:save, update, saveOrUpdate,delete;还有其他很多操作没有用过:persist(), merge(), lock(), refresh(), evict(), replicate() ,有必要弄清楚这些方法分别是做什么, 实体对象的状态会发生什么变化?

[转]Hibernate Session各种状态转换方法分析
先看看这些方法中,从javadoc的注释可以得出: 
临时 —> 持久 
save,persist,saveOrUpdate

托管 —> 持久 
update,saveOrUpdate,saveOrUpdateCopy , merge,lock,replicate,refresh

持久 —> 托管 
evict

持久 —> 临时 
delete

根据以上,可以看出托管->持久的方法是最多的。 
那么以上各类情况下,各个方法有什么区别?应该怎样取舍?在hibernate3.2环境下,我得出以下结论: 
1. save和perisit 
几乎一样,都是持久化一个临时对象; 
只是persist持久化的时间可能推迟到flunsh之前,而且perisit传入的对象为托管对象时,会报错,而save托管对象不会报错只是将id置null。

可以看出,在持久化一个临时对象时,只用save就行了。

2. saveOrUpdate和merge 
saveOrUpdate将unsaved对象持久化或托管对象持久化; 
merge,从名字也能猜到是合并,跟saveOrUpdate相似,可以持久化托管和临时对象。 
不同的是:在更新时候,merge将托管对象的属性复制到session中有相同标识符(但不相等)的持久对象(如果不存在,就从db load),也就是先select 后 update;倘若找不到相同标识符的对象,则置id为null,保存临时对象。返回的是持久对象,但是merge传入的对象还是托管的。

可以看出,只有在session中已经存在一个具有相同标识符的持久对象的时候,应该采用merge,此时用saveOrUpdate会报错。当然如果碰到这类情形,将对象属性copy到已经持久化的那个相同标识符对象上也是可以的,正因为如此我一般都没用过merge。再者merge在session中不存在相同标识对象时,会多一条select,往往我们并不需要。

3. merge和replicate 
replicate,通过复制来持久化当前已经脱离session的托管对象,这点上看有点像merge,但是当传入一个临时对象则会报错,而且replicate后的传入的那个对象将是持久的,这也是跟merge不同。 
通过参数ReplicationMode可以控制遇到相同记录时的行为。 
如果是 ReplicationMode.EXCEPTION,则在复制时如果有重复的行数据,则抛出异常。ReplicationMode.IGNORE则忽略 异常。 
ReplicationMode.OVERWRITE则会覆盖掉已有行数据。ReplicationMode.LATEST_VERSION则是在有重复时使用最新的版本进行控制。

可以看出,replicate在执行复制的时候,比起merge还是有更多可控行为,ReplicationMode.LATEST_VERSION还可以保证并发修改时只更新最新的版本。

4. lock和refresh 
相类似的,都将托管对象又重新持久化,而且可以指定查询时候的锁: 
    * 当用户显式的使用数据库支持的SQL格式SELECT ... FOR UPDATE 发送SQL的时候,锁定级别设置为LockMode.UPGRADE 
    * 当用户显式的使用Oracle数据库的SQL语句SELECT ... FOR UPDATE NOWAIT 的时候,锁定级别设置LockMode.UPGRADE_NOWAIT 
    *当Hibernate在“可重复读”或者是“序列化”数据库隔离级别下读取数据的时候,锁定模式 自动设置为LockMode.READ。这种模式也可以通过用户显式指定进行设置。 
    *LockMode.NONE 代表无需锁定。在Transaction结束时, 所有的对象都切换到该模式上来。与session相关联的对象通过调用update() 或者saveOrUpdate()脱离该模式。 
以上只有 LockMode.NONE,先从缓存查找持久对象;其他的都直接从数据库查找。

有些不同的是,lock还有检查对象版本的能力,如果指定的锁定模式是READ, UPGRADE 或 UPGRADE_NOWAIT,那么Session.lock()就 执行版本号检查。

refresh提供了比load更方便的查找能力,一个刚脱离了session的持久对象,如果用load还需要用id查找,那么refresh就可以直接传入托管对象刷新其状态了。

5. delete和evict 
evict,从session的缓存中去除当前实例。执行后对象的改变将不再和数据库保持同步。当指定级联风格为'evict’时,会级联操作关联对象。在用于批量操作的时候,清空缓存,防止内存紧张。 
delete,也会从session的缓存中去除当前实例,但flunsh时会执行数据库delete,之后对象就成了临时状态。 
可以看出delete比起evict,不仅从session删除,还会从数据库删除。

参考文献: 
http://www.redsaga.com/hibernate-ref/3.x/zh-cn/html/objectstate.html 
http://loveexception.iteye.com/blog/29353

[转]Hibernate Session各种状态转换方法分析的更多相关文章

  1. Hibernate3回顾-5-简单介绍Hibernate session对数据的增删改查

    5. Hibernate对数据的增删改查 5.1Hibernate加载数据 两种:get().load() 一. Session.get(Class arg0, Serializable arg1)方 ...

  2. hibernate 异常分析:java.lang.NoClassDefFoundError: org/hibernate/Session

    原因: NoClassDefFoundError的含义就是说编译器找不到org/hibernate/Session这个类的定义 解决方法: 1.检查java中是否导入hibernate 包 impor ...

  3. Hibernate Session & Transaction详解

    Hibernate Session & Transaction详解 HIbernate中的Session Session是JAVA应用程序和Hibernate进行交互时使用的主要接口,它也是持 ...

  4. 1.1Hibernate持久化类和Hibernate持久化对象状态

    一.持久化对象po类 1.po定义 PO,是Persistent Object的缩写,是持久化类.PO是由PO=POJO+hbm映射配置组成. 2.通俗理解 PO类即持久化类,其实就是一个普通的Jav ...

  5. SSH框架之-hibernate 三种状态的转换

    一.遇到的神奇的事情 使用jpa操作数据库,当我使用findAll()方法查处一个List的对象后,给对这个list的实体进行了一些操作,并没有调用update 或者 saveOrUpdate方法,更 ...

  6. Hibernate对象的状态

    站在持久化的角度, Hibernate 把对象分为 4 种状态: 1. 持久化状态 2. 临时状态 3. 游离状态 4. 删除状态 Session 的特定方法能使对象从一个状态转换到另一个状态. 下面 ...

  7. 简单理解Hibernate三种状态的概念及互相转化

    本文描述了Hibernate三种状态的概念及互相转化.Java对象的生命周期中有三种状态,而且互相转化.它们分别是临时状态,持久化状态,以及游离状态. AD:WOT2015 互联网运维与开发者大会 热 ...

  8. 第二节 hibernate session介绍以及session常用方法介绍

    原创地址:http://www.cnblogs.com/binyulan/p/5628579.html Session是java应用程序和hibernate框架之间的一个主要接口.它是从持久化服务中剥 ...

  9. Hibernate对象的状态和映射

    一. Hibernate对象的状态 实体对象的三种状态: 1) 暂态(瞬时态)(Transient)---实体在内存中的*存在,它与数据库的记录无关. po在DB中无记录(无副本),po和sessi ...

随机推荐

  1. c#:排序

    http://www.cnblogs.com/end/archive/2011/10/22/2220940.html 选择排序 冒泡排序 快速排序 插入排序 希尔排序 归并排序 基数排序 计数排序 小 ...

  2. Kafka 消息存储及检索(作者:杜亦舒)

    Kafka 消息存储及检索 原创 2016-02-29 杜亦舒 性能与架构 Kafka是一个分布式的消息队列系统,消息存储在集群服务器的硬盘Kafka中可以创建多个消息队列,称为topic,消息的生产 ...

  3. sql server异地备份数据库

    --注意:异地备份数据库,需要先开启备份文件夹的网络共享,数据库选择master --打开允许执行xp_cmdshell exec master..xp_cmdshell 'net use \\192 ...

  4. [百度空间] [转]DLL地狱及其解决方案

    DLL地狱及其解决方案 原作者:Ivan S Zapreev 译者:陆其明概要 本文将要介绍DLL的向后兼容性问题,也就是著名的“DLL Hell”问题.首先我会列出自己的研究结果,其中包括其它一些研 ...

  5. MongoDB命令学习

    mongodb不像关系型数据库有很强大的GUI客户端,虽然mongodb也有,但功能和稳定性实在不敢恭维,所以操作mongodb我们大部分 都是用类似cmd命令的方式(mongodb称为shell操作 ...

  6. 详细介绍android rom移植知识普及

    详细介绍android rom移植知识普及 最近接到很多兄弟们的求助,也回答过无数个和下面这个问题类似的问题: 如何编译android 原生代码得到一个rom,然后跑到某某手机上. 鉴于很多兄弟对这块 ...

  7. Html事件冒泡

    原以为span不同于input,事件冒泡会被父级标签吞噬,写了个测试事件冒泡的Demo,发现并不是想得那样.另外:event.stopPropagation()以及event.stopImmediat ...

  8. EasyUI中Tabs添加远程数据的方法。

    tabs加载远程数据: $(function () { $("#btnquery").click(function () { if (!$("#tcontent&quot ...

  9. Python爬虫之urllib模块2

    Python爬虫之urllib模块2 本文来自网友投稿 作者:PG-55,一个待毕业待就业的二流大学生. 看了一下上一节的反馈,有些同学认为这个没什么意义,也有的同学觉得太简单,关于Beautiful ...

  10. ensureCapacity增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。

    扩容原则: 若参数值大于底层数组长度的1.5倍,则数组的长度就扩容为这个参数值:若小于底层数组长度的1.5倍,则数组长度就扩容为底层数组长度的1.5倍. ensureCapacity提高效率 fina ...