今天做了个测试,写了个测试用例来看看merge与update时控制台打印出来的日志有什么不一样。实体bean很简单,就id和name两个字段,接下来分别给出以下几种测试情形的控制台日志内容:

1. 数据库记录已存在,更改person的name为一个新的name。

merge方法打印出的日志如下:
Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_ from person person0_ where person0_.id=?
Hibernate: update person set name=? where id=?

update方法打印出的日志如下:
Hibernate: update person set name=? where id=?

2. 数据库记录已存在,更改person的name和数据库里对应id记录的name一样的值。

merge方法打印出的日志如下:
Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_ from person person0_ where person0_.id=?
此处相对于第一种情形少了update的动作

update方法打印出的日志如下:
Hibernate: update person set name=? where id=?

3. 数据库记录不存在时,也就是你传的实体bean的ID在数据库没有对应的记录。

merge方法打印出的日志如下:
Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_ from person person0_ where person0_.id=?
Hibernate: insert into person (name) values (?)

如果没有对应的记录,merge会把该记录当作新的记录来插入。此处我很疑惑,因为我传得person实体对象里写明了id值的,它为什么还会做插入的动作呢?

网上朋友的回答:因为没有查到对象没有办法做匹配,不能修改,就往数据库里重新插入一条数据

update方法打印出的日志如下:
Hibernate: update person set name=? where id=?
2009-11-22 20:59:55,359 ERROR [org.hibernate.jdbc.AbstractBatcher] - Exception executing batch:

org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

以下的内容摘抄自网上:
  当我们使用update的时候,执行完成后,我们提供的对象A的状态变成持久化状态。

  但当我们使用merge的时候,执行完成,我们提供的对象A还是脱管状态,hibernate或者new了一个B,或者检索到 一个持久对象B,并把我们提供的对象A的所有的值拷贝到这个B,执行完成后B是持久状态,而我们提供的A还是托管状态。

网上朋友的总结:

merge(oldObj) 操作如下:

if(oldObj没有id) {
      添加操作  
} else {
     if(根据oldObj.id在Hibernate Context中没有找到对象) {
          加载得到newObj;
          if(newObj == null) {
               添加操作
        }

}else{
         newObj
     }
  
    if(oldObj里面的属性 和newObj不一致) {
      更新操作
}

}

Hibernate参考书中hibernate对象三种状态

Hibernate定义并支持下列对象状态(state):

  • 瞬时(Transient) - 由new操作符创建,且尚未与Hibernate
    Session
    关联的对象被认定为瞬时(Transient)的。瞬时(Transient)对象不会被持久化到数据库中,也不会被赋予持久化标识
    (identifier)。 如果瞬时(Transient)对象在程序中没有被引用,它会被垃圾回收器(garbage collector)销毁。
    使用Hibernate
    Session可以将其变为持久(Persistent)状态。(Hibernate会自动执行必要的SQL语句)

  • 持久(Persistent) - 持久(Persistent)的实例在数据库中有对应的记录,并拥有一个持久化标识(identifier)。 持久(Persistent)的实例可能是刚被保存的,或刚被加载的,无论哪一种,按定义,它存在于相关联的Session作用范围内。 Hibernate会检测到处于持久(Persistent)状态的对象的任何改动,在当前操作单元(unit
    of work)执行完毕时将对象数据(state)与数据库同步(synchronize)。 开发者不需要手动执行UPDATE。将对象从持久(Persistent)状态变成瞬时(Transient)状态同样也不需要手动执行DELETE语句。

  • 脱管(Detached) - 与持久(Persistent)对象关联的Session被关闭后,对象就变为脱管(Detached)的。 对脱管(Detached)对象的引用依然有效,对象可继续被修改。脱管(Detached)对象如果重新关联到某个新的Session上, 会再次转变为持久(Persistent)的(在Detached其间的改动将被持久化到数据库)。
    这个功能使得一种编程模型,即中间会给用户思考时间(user think-time)的长时间运行的操作单元(unit of work)的编程模型成为可能。 我们称之为应用程序事务,即从用户观点看是一个操作单元(unit of work)。

Hibernate的merge与update方法的区别的更多相关文章

  1. Save()saveOrUpdate()Hibernate的merge()方法

    Save save()方法能够保存实体到数据库,正如方法名称save这个单词所表明的意思.我们能够在事务之外调用这个方法,这也是我不喜欢使用这个方法保存数据的原因.假如两个实体之间有关系(例如empl ...

  2. Hibernate的load和get方法的区别

    这次我们聊一下Hibernate3.2 Session加载数据时get和load方法的区别,我总结的如下: 1. 对于get方法,hibernate会确认一下该id对应的数据是否存在,首先在sessi ...

  3. 【hibernate merge】session1.merge(T entity)方法的含义和update方法的区别

    注意:  MERGE语句是SQL语句的一种.在SQL Server.Oracle数据库中可用,MySQL.PostgreSQL中不可用. 1>session1.merge(T entity) 合 ...

  4. hibernate 关于session的update方法

    先看写代码的方法: @Test     public void testUpdate3() {                         Teacher t = new Teacher();   ...

  5. hibernate中load和get方法的区别

    1.读取时机不同(当lazy=true的时候)    load是采用延迟机制(load语句不读库,等使用非主键时才去读库),而get不采用延  迟机制(get语句时马上读库): 2.搜索不到数据时的情 ...

  6. Hibernate Session的delete()方法

    本文介绍Hibernate Session的delete()方法.delete()方法用于从数据库中删除与Java对象对应的记录.对应游离对象和持久化对象,delete语句会做出不同的反应. AD:  ...

  7. [原创]java WEB学习笔记79:Hibernate学习之路--- 四种对象的状态,session核心方法:save()方法,persist()方法,get() 和 load() 方法,update()方法,saveOrUpdate() 方法,merge() 方法,delete() 方法,evict(),hibernate 调用存储过程,hibernate 与 触发器协同工作

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  8. Hibernate merge和update的区别

    今天做了个测试,写了个测试用例来看看merge与update时控制台打印出来的日志有什么不一样.实体bean很简单,就id和name两个字段,接下来分别给出以下几种测试情形的控制台日志内容: 1. 数 ...

  9. hibernate的集中持久化方法的区别

    一.预备知识 在所有之前,说明一下,对于hibernate,它的对象有三种状态,transient.persistent.detached 下边是常见的翻译办法: transient:瞬态或者自由态 ...

随机推荐

  1. java util - json转换工具 gson

    需要 gson-2.7.jar 包 package cn.java.gson; import com.google.gson.JsonElement; import com.google.gson.J ...

  2. pycharm配置Git托管

    利用Pycharm和github管理代码转载https://www.cnblogs.com/feixuelove1009/p/5955332.html git教程--廖雪峰git教程  转载https ...

  3. 华为liteos了解(一)

    我来补充一下,从@華仔答案的提供的wiki中看,随便翻了一下,内核部分和协议栈的接口部分代码风格完全不一致.协议栈和相关的代码应该是直接使用或者修改了uIP (micro IP)的实现,所以整体感觉应 ...

  4. Git-GIt检出

    实际上在执行重置命令的时候没有使用任何参数对所要重置的分支名进行设置,这是因为重置命名实际上所针对的是头指针HEAD.之所以没有改变HEAD的内容是因为HEAD指向了一个引用refs/heads/ma ...

  5. XmlSerializer 短信备份

    package com.itheima.mobileguard.utils; import java.io.File; import java.io.FileNotFoundException; im ...

  6. Redis数据结构以及Strings型操作

    Redis数据结构图: Strings型   <String key,String value>: keys * 查看所有key get 获取key的value值 append 向key对 ...

  7. Java-读取txt生成excel

    本段代码的目的是从txt文本中读取相应格式的数据,然后写入到对应格式的excel文档中 在敲本段代码的时候,也学习了一些其它知识点,如下: 1.byte[] b_charset= String.get ...

  8. 步骤详解安装Apache web服务器

    1.在上右键è安装 安装后apache web服务器自动启动. 在右下角出现. Apache安装之后有一个默认的网站目录 在浏览器上通过网站就可以访问到该目录下的文件. 2.测试 在浏览器输上请求lo ...

  9. 【Remove Duplicates from Sorted List II 】cpp

    题目: Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct  ...

  10. Uncaught TypeError: Cannot read property of undefined In JavaScript

    当脚本遇到未初始化的变量或对象时,通常会抛出如上图所示的错误. Decription 'Undefined'是全局对象的属性.如果没有为变量赋值,则为'undefined'类型.当求值变量没有任何赋值 ...