`
littie1987
  • 浏览: 133908 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Hibernate的merge()方法

阅读更多

      下面来讲讲Hibernate的merge方法。我打算按照hibernate对象生命周期的三个状态来讲。

1:如果POJO对象处于游离态,我所说的游离态是指该对象的id值为空。hibernate判断一个对象在数据库中是否存在不是看对象的其他信息,而是判断该id在数据库中是不是存在。如果id为空,那自然是不存在,所以当我们调用merge方法的时候,就会直接执行插入操作。这一点有点像saveorupdate()方法。看一段代码:

		User user = new User();
		//user.setId(4);
		user.setUsername("heyuanling2");
		user.setAge(23);
		user.setSex("w");
		user.setPassword("heyuanling");
		Session session = this.getSession();
		Transaction tr = session.beginTransaction();
		//User exituser = (User)session.get(User.class, new Integer(1));
		session.merge(user);
		tr.commit();

 

再看hibernate的sql语句:

Hibernate: 
    select
        max(id) 
    from
        user_
Hibernate: 
    insert 
    into
        user_
        (username, password, sex, age, birthday, other, id) 
    values
        (?, ?, ?, ?, ?, ?, ?)

 

二:脱管态:如果我们把上面代码里//user.setId(4);的注释去掉,那么它就变成了脱管的对象了(其实从游离到脱管就这么简单,没有官方说的那么邪乎...)。这是我们再来看控制台的sql打印:

Hibernate: 
    select
        user0_.id as id4_0_,
        user0_.username as username4_0_,
        user0_.password as password4_0_,
        user0_.sex as sex4_0_,
        user0_.age as age4_0_,
        user0_.birthday as birthday4_0_,
        user0_.other as other4_0_ 
    from
        user_ user0_ 
    where
        user0_.id=?

 看到没有,因为id不为空了,所以hibernate就不会再insert了。由于该对象的信息和数据库里的一模一样,所以hibernate只执行了一个select语句,并没有update,如果我们把字段的值做稍微的变动,那么控制台打印的sql语句还应该有一条update语句。就这一点来说,merge还有和saveorupdate()方法一样。

 

 

三:持久态:持久态更好理解。如果我们从数据库里get一条记录,那么这条记录就处于持久态,如果再调用merge,那么hibernate就会先判断该记录是否被修改,没有则什么也不干,修改了就update。这一点还是和saveorupdate()有点像。

Session session = this.getSession();
Transaction tr = session.beginTransaction();
User exituser = (User)session.get(User.class, new Integer(1));
exituser.setAge(11);
session.merge(exituser);
tr.commit();
session.close();

 再看控制台打印结果:

Hibernate: 
    select
        user0_.id as id4_0_,
        user0_.username as username4_0_,
        user0_.password as password4_0_,
        user0_.sex as sex4_0_,
        user0_.age as age4_0_,
        user0_.birthday as birthday4_0_,
        user0_.other as other4_0_ 
    from
        user_ user0_ 
    where
        user0_.id=?
Hibernate: 
    update
        user_ 
    set
        username=?,
        password=?,
        sex=?,
        age=?,
        birthday=?,
        other=? 
    where
        id=?

  如果没有对记录进行修改则不会有后面的那条update语句。

 

那么merge和saveorupdate()到底有什么区别呢?看一段代码:

Session session = this.getSession();
Transaction tr = session.beginTransaction();
User exituser = (User)session.get(User.class, new Integer(1));
tr.commit();
session.close();
session = getSession();
tr = session.beginTransaction();
User exituser2 = (User)session.get(User.class, new Integer(1));
session.update(exituser);
tr.commit();
session.close();

 运行上面的代码,hibernate给我们报了一个错误:a different object with the same identifier value was already associated with the session。意思是,在session缓存中以两个标识相同的对象,这是不可以的。那么,吧update改成merge会怎么样呢?改为merge后,一切OK,运行正常。其实merge在执行更新之前会将两个标识符相同的对象进行合并,具体合并的方向是向exituser2合并。

 

注意:merge方法在执行之前都回去缓存中找是不是有相应的记录,也就是会有一条select语句,执行改语句的目的是为了判断该对象是否被修改了。而update就不管这些,直接就一条update语句。

分享到:
评论
9 楼 vivian123an 2015-01-11  
http://stackoverflow.com/questions/8846017/hibernate-merge
8 楼 zuoguodong 2014-12-15  
7 楼 379855529 2014-06-29  
好详细的分析啊,受教了。
6 楼 zouqone 2014-03-16  
keryluo 写道
最后一个例子,如果改成下面的代码:
Session session = this.getSession();
Transaction tr = session.beginTransaction();
User exituser = (User)session.get(User.class, new Integer(1));
exituser.setUsername("test1"); 
tr.commit();
session.close();
session = getSession();
tr = session.beginTransaction();
User exituser2 = (User)session.get(User.class, new Integer(1));
exituser2.setUsername("test2"); 
session.merge(exituser);
tr.commit();
session.close();

执行之后,发现用户的名字被改成了“test1”,而不是”test2“;

所以说: 具体合并的方向是向exituser2,感觉与执行的结果不符合。
准确的说,应该是把 exituser 的对象拷贝到 exituser2 然后执行更新操作。

LZ 何解??



exituser2.setUsername("test2"); 
session.merge(exituser);
tr.commit();
session.close();
改成
exituser2.setUsername("test2"); 
session.merge(exituser2);
tr.commit();
session.close();
试试
5 楼 zqb666kkk 2013-11-05  
跟 oracle的 merge语法差不多
4 楼 keryluo 2013-10-03  
最后一个例子,如果改成下面的代码:
Session session = this.getSession();
Transaction tr = session.beginTransaction();
User exituser = (User)session.get(User.class, new Integer(1));
exituser.setUsername("test1"); 
tr.commit();
session.close();
session = getSession();
tr = session.beginTransaction();
User exituser2 = (User)session.get(User.class, new Integer(1));
exituser2.setUsername("test2"); 
session.merge(exituser);
tr.commit();
session.close();

执行之后,发现用户的名字被改成了“test1”,而不是”test2“;

所以说: 具体合并的方向是向exituser2,感觉与执行的结果不符合。
准确的说,应该是把 exituser 的对象拷贝到 exituser2 然后执行更新操作。

LZ 何解??
3 楼 keryluo 2013-10-03  

领教了,写的非常的好的。
很透彻!!!
2 楼 keryluo 2013-09-21  
写的很好,分析的很透彻。
1 楼 Zenglihuan 2013-06-06  
写得很棒

相关推荐

    Hibernate中的merge使用详情解说

    在 Hibernate 中,merge 方法是非常重要的一个方法,它能够帮助开发者轻松地处理数据的更新和插入操作。那么,merge 方法到底如何工作的呢?下面,我们将对 merge 方法进行详细的解释。 首先,merge 方法是一个可以...

    Hibernate merge、update与saveOrUpdate方法的区别

    ### Hibernate merge、update与saveOrUpdate方法的区别 在Hibernate框架中,`merge`、`update`与`saveOrUpdate`这三个方法都是用于更新或保存实体对象到数据库中的,但它们之间存在着重要的区别,这些区别主要体现...

    Hibernate save persist merge探究

    本文将深入探讨Hibernate中的save、persist和merge这三个方法,帮助开发者更好地理解它们的用法和内在机制。 一、save()方法 save()是Hibernate早期版本中最常用的方法,用于将对象持久化到数据库中。当调用Session...

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

    综上所述,`merge()`方法是Hibernate中处理对象状态转换和数据同步的重要工具。它能够处理各种对象状态,确保数据的一致性和完整性,同时避免了可能的冲突。在设计和实现业务逻辑时,理解并正确使用`merge()`对于...

    merge的注意事项

    在探讨“merge的注意事项”这一主题时,我们深入解析Hibernate框架中merge操作的特性与应用场景,以及它与其他数据持久化方法的区别,特别是与saveOrUpdate函数的对比。这不仅有助于理解Hibernate的核心机制,还能...

    Hibernate:不容易理解的 lock 和 merge.docx

    `merge` 方法则是 Hibernate 中用于将游离状态的对象合并到持久化状态的过程。它的主要职责如下: 1. **保存新对象**:如果传入的对象是未保存的新对象(unsaved),`merge` 方法会创建该对象的一个拷贝,并调用 `...

    hibernate各种常用方法的详解

    本文将详细介绍 Hibernate 中常用的几种方法,包括 `save`, `update`, `saveOrUpdate`, `merge` 等,帮助开发者更深入地理解 Hibernate 的工作原理及其使用方式。 #### 二、Hibernate 对象状态管理 在 Hibernate ...

    session中merge和update的区别

    Hibernate中session的merge以及update方法

    Hibernate框架jia包

    - **Session**:它是与数据库交互的主要接口,提供了保存、更新、删除和检索对象的方法。 - **Transaction**:用于管理数据库事务,确保数据的一致性。 - **Query**:提供了执行HQL或Criteria查询的API。 4. **...

    Hibernate实战

    这涉及到使用Session的save()、saveOrUpdate()、load()、get()、update()、merge()和delete()方法。同时,还会讨论事务管理和并发控制,确保数据的一致性和完整性。 查询语言在Hibernate中主要有两种:HQL...

    Hibernate学习文档集合

    它还涵盖了持久化对象的状态管理(瞬时态、持久态、游离态和删除态),以及Entity的save()、update()、merge()、delete()方法的具体使用场景。此外,还讲解了Criteria查询、HQL(Hibernate Query Language)和JPQL...

    hibernate常见异常

    * 使用 session.merge(object),Hibernate 里面自带的方法,推荐使用。 了解 Hibernate 中的常见异常是非常重要的。通过了解这些异常的原因和解决方案,我们可以更好地使用 Hibernate,提高开发效率和质量。

    Hibernate对象状态以及各种保存方法的区别

    以下是 Hibernate 中对象的三种状态以及相关的保存方法: 1. **瞬时对象(Transient Objects)** - 当使用 `new` 关键字创建一个对象时,它处于瞬时状态。这种状态的对象与数据库中的任何记录没有关联,只存在于...

    hibernate_reference中文版和Hibernate中文手册

    5. CRUD操作:Hibernate提供了便捷的方法来完成创建(save()、persist())、读取(get()、load()、query())、更新(update()、merge())和删除(delete())对象的操作。其中,HQL(Hibernate Query Language)和...

    hibernate-release-5.4.25.Final_Hibernate5.4.25_hibernate所需jar包_源

    1. 持久化操作:通过SessionFactory创建Session,然后调用Session的save()、update()、delete()和merge()方法,实现对象的增删改操作。 2. 查询:使用Query或Criteria API,支持复杂条件、分页、排序等查询,甚至...

    Hibernate语句

    接下来,我们将深入探讨Hibernate的方法使用,包括XML配置、Session管理和Criteria查询。 **一、Hibernate的XML配置** Hibernate的核心配置文件是`hibernate.cfg.xml`,它包含了数据库连接信息、实体类映射和...

    hibernate源码release-4.1.4.Final版

    Hibernate提供了save()、update()、merge()和delete()方法来处理对象的持久化状态。其中,save()适合新对象的插入,update()用于已存在对象的更新,merge()则是合并当前对象状态到持久化对象,delete()则删除对象。 ...

    Hibernate update问题

    在处理数据更新时,Hibernate提供了多种方法,但同时也可能会遇到一些常见问题。本篇文章将深入探讨Hibernate更新机制及其可能遇到的问题,旨在帮助开发者更好地理解和解决这些问题。 1. **基本更新操作** ...

    HibernateDemo(hibernate基本用法演示)

    - **更新(Update)**:修改实体后调用 `update()` 或 `merge()` 更新数据库中的记录。 - **删除(Delete)**:使用 `delete()` 方法移除实体。 5. **事务管理**:在数据库操作中使用 `Transaction` 对象进行事务...

    hibernate-5.2.15. 最新jar包

    在业务逻辑处理中,通常使用Session的beginTransaction、save/merge、flush和commit等方法来完成数据库操作。 3. **Query和Criteria API**:提供两种方式执行查询,一是HQL(Hibernate Query Language),类似于SQL...

Global site tag (gtag.js) - Google Analytics