`

hibernate merge与update区别

    博客分类:
  • S2SH
阅读更多
今天做了个测试,写了个测试用例来看看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值的,它为什么还会做插入的动作呢?(如果使用不好,则会在更新时,不会更新而是新增一行记录!!!)
在做更新操作时,在merge之前先要持久化一下?



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方法,如果数据库中有该记录,则更新该记录,如果不存在该记录,则进行insert操作。

使用update的话,会无条件执行update。

也就是说如果数据库中有该记录的话,merge和update是一样的。
但是如果数据库中没有该记录,使用merge执行insert,不会报错,而使用update会报错。


不同之处在于,update可以持久化类,merge不行 --- 重要

---------------------------------------

假设有个Student stu类,session.update(stu),merge也是一样。
不同之处在于,update可以持久化类,merge不行,执行session.merge(stu)之后,stu对象如果之前不是持久化状态,stu对象依然不会被关联到session上。

----------------------------------------

谁懂得hibernate的merge方法?

我使用merge方法。老是报could not load an entity的异常。
配置文件,一定没有问题。
于是,我写了个junit的单元测试。这个单元测试继承了HibernateDaoSupport,并注入了sessionFactory,并调用
this.getHibernateTemplate.merge 方法,还是could not load an entity.

是我对merge理解有问题,还是其他什么问题?

//单元测试如下

public class MergeTest extends HibernateDaoSupport {

@Test
public void testMerge(){

//获取spring配置
ApplicationContext act = new FileSystemXmlApplicationContext("/WebRoot/WEB-INF/applicationContext.xml");

//注入sesssionFactory
this.setSessionFactory((SessionFactory)act.getBean("sessionFactory"));

//创建一个模拟的DocumentCatalog 数据中已经有个 id = 1的数据
DocumentCatalog dc = new DocumentCatalog();

dc.setId(1);
dc.setName("crying!!!!!");

//我认为,这时候,数据库中的 id = 1的数据,会被update,但是,发生could not load an entity错误。
//数据库映射没有错误,换成update就能顺利更新。
this.getHibernateTemplate().merge(dc);

}
}


用update是直接把实体和数据库同步,而是要merge方法时 merge操作的是实体的代理对象,所以我们用它时一定要把它放到事务中执行,否则会报could not load an entity异常,
意思是在:this.getHibernateTemplate().merge(dc);语句前面开启一个事务就OK




=========================================================

理一下思路:(没有验证)

使用merge方法时,
如果存在一个持久化的对象,则执行 update 操作。
如果不存在一个持久化的对象,则进行插入操作。

所以,对象需要先持久化后,再进行 merge() 。这里的持久化不是数据库中是否有这条记录,而是 Hibernate 中数据的状态。如果数据库中存在一条记录,而没有被 Hibernate 持久化,使用 merge() 时,仍然执行的是新增一条记录操作。而不是更新操作。












-
引用:
http://www.cnblogs.com/hyteddy/archive/2011/05/10/2041762.html
分享到:
评论

相关推荐

    Hibernate merge、update与saveOrUpdate方法的区别

    Hibernate merge、update与saveOrUpdate方法的区别

    session中merge和update的区别

    Hibernate中session的merge以及update方法

    Hibernate中的merge使用详情解说.docx

    当ID在数据库中能找到的时候,update与merge的执行效果都是更新数据,发出update语句; 如果没有设置ID的话,则这个对象就当作瞬态处理: 用update的话,由于没有ID,所以会报异常,merge此时则会保存数据,根据ID...

    save, saveOrUpdate, persist, merge, update 区别.docx

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

    Hibernate的Session的javadoc

    我身边的朋友经常会分不清save、saveOrUpdate、update的区别,lock、merge、replicate、refresh、evict甚至不知道是干什么用的。而且关于实体对象的生命周期也有很多概念不清,分不清transient、persistent、...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

    第24章 Hibernate与Struts框架  24.1 实现业务数据  24.2 实现业务逻辑  24.3 netstore应用的订单业务  24.4 小结 第25章 Hibernate与EJB组件  25.1 创建EJB组件  25.1.1 编写Remote接口  25.1.2 编写Home...

    Hibernate注释大全收藏

    AUTO 生成器,适用与可移值的应用,多个@Id可以共享同一个 identifier生成器,只要把generator属性设成相同的值就可以。通过@SequenceGenerator 和 @TableGenerator 可以配置不同的 identifier 生成器。 table=...

    精通hibernate:对象持久化技术孙卫琴第二版part2

    本章主要介绍单个持久化类与单个数据库表之间进行映射的方法,尤其是当持久化类的属性不和数据库表的字段一一对应时的映射技巧。 5.1 持久化类的属性及访问方法 101 5.1.1 基本类型属性和包装类型属性 102 5.1.2 ...

    Hibernate注解

    * updatable 可选,该列是否作为生成的update语句中的一个列(默认值true) * columnDefinition 可选,为这个特定列覆盖sql ddl片段(这可能导致无法在不同数据库间移植) * table 可选,定义对应的表(默认为主表)...

    精通Hibernate:对象持久化技术第二版part3

    本章主要介绍单个持久化类与单个数据库表之间进行映射的方法,尤其是当持久化类的属性不和数据库表的字段一一对应时的映射技巧。 5.1 持久化类的属性及访问方法 101 5.1.1 基本类型属性和包装类型属性 102 5.1.2 ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

    第24章 Hibernate与Struts框架  24.1 实现业务数据  24.2 实现业务逻辑  24.3 netstore应用的订单业务  24.4 小结 第25章 Hibernate与EJB组件  25.1 创建EJB组件  25.1.1 编写Remote接口  25.1.2 编写Home...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

    第24章 Hibernate与Struts框架  24.1 实现业务数据  24.2 实现业务逻辑  24.3 netstore应用的订单业务  24.4 小结 第25章 Hibernate与EJB组件  25.1 创建EJB组件  25.1.1 编写Remote接口  25.1.2 编写Home...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

    第24章 Hibernate与Struts框架  24.1 实现业务数据  24.2 实现业务逻辑  24.3 netstore应用的订单业务  24.4 小结 第25章 Hibernate与EJB组件  25.1 创建EJB组件  25.1.1 编写Remote接口  25.1.2 编写Home...

    Hibernate_Annotation关联映射

    这种方案不会得到什么明显的优化,而且还会增加一些附加的UPDATE语句。 单向: 通过在被拥有的实体端(owned entity)增加一个外键列来实现一对多单向关联是很少见的,也是不推荐的,建议通过一个联接表来实现这种...

    低清版 大型门户网站是这样炼成的.pdf

    1.1 大型门户网站与小型企业网站的区别 3 1.2 高性能、高负载门户网站架构剖析 9 1.2.1 服务器操作系统的选择 10 1.2.2 dns服务器bind 16 1.2.3 cache服务器squid 18 1.2.4 带负载均衡的http服务器apache 19 ...

    Java通用代码生成实用程序XDoclet(源码包)

    ${conf.struts}" mergeDir="${conf-merge.struts}" /> 像@hibernate.clas、@hibernate.property、@struts.action-forward等等这些特定的注释标签需要去查XDoclet的相关文档了,Xdoclet对目前流行的多种框架、...

    java语言hebernate代码

    在我们程序当中调用save,update,get,load,saveOrUpdate,merge,list c:游离状态(脱管状态) 对象从session作用域分离出来的时候我们叫做游离(脱管) 即:调用delete,clear,evict等方法时

    支持多数据库的ORM框架ef-orm.zip

    事实上针对单个对象的get/load/persist/save/update/merge/saveOrUpdate API和Criteria API本来就为一体,只不过是历史的原因被人为割裂成为两套数据库操作API罢了。  因此,对于关系型数据库而言——Entity和...

Global site tag (gtag.js) - Google Analytics