其他分享
首页 > 其他分享> > 孙卫琴的《精通JPA与Hibernate》的读书笔记:EntityManager和Session的merge()方法详解

孙卫琴的《精通JPA与Hibernate》的读书笔记:EntityManager和Session的merge()方法详解

作者:互联网

JPA API 的EntityManager 以及Hibernate API的Session都有一个merge()方法,它们的作用相同,能够把一个游离对象的属性复制到一个持久化对象中。

当Session用update()方法关联一个游离对象时,如果在持久化缓存中已经存在一个同类型的并且OID相同的持久化对象,那么update()方法会抛出NonUniqueObjectException:

customer1.setName("Jack");//假定customer1为游离对象,OID为1

Session session=sessionFactory.openSession();
tx = session.getTransaction(); 
tx.begin(); //开始一个事务

//session加载OID为1的Customer持久化对象
Customer customer2=session.get(Customer.class, Long.valueOf(1));
                                       
//把OID为1的customer1游离对象加入到持久化缓存中
session.update(customer1);  //抛出NonUniqueObjectException

tx.commit();
session.close();

下面的代码把update()方法改为merge()方法:

customer1.setName("Jack");//假定customer1为游离对象,OID为1

Session session=sessionFactory.openSession();
tx = session.getTransaction(); 
tx.begin(); //开始一个事务

//session加载OID为1的Customer持久化对象
Customer customer2=session.get(Customer.class, Long.valueOf(1));
                                        
//把customer1对象的属性复制到持久化缓存中的相应持久化对象中
Customer customer3=(Customer)session.merge(customer1);  

customer1==customer2; //false
customer1==customer3; //false
customer2==customer3; //true

//执行update语句,把CUSTOMERS表中ID为1记录的NAME字段改为Jack
tx.commit(); 

session.close();
return customer3;

Session的merge()方法的处理流程如下:
(1)根据customer1游离对象的OID到持久化缓存中查找匹配的持久化对象。在本例中,找到了匹配的customer2持久化对象,就把customer1游离对象的属性复制到customer2持久化对象中,计划执行一条update语句,再返回customer2持久化对象的引用,所以表达式“customer2==customer3”的值为true。

(2)如果在持久化缓存中没有找到与customer1游离对象的OID一致的Customer持久化对象,那么就试图根据这个OID从数据库中加载Customer持久化对象。如果在数据库中存在这样的Customer持久化对象,就把customer1游离对象的属性复制到这个刚加载的Customer持久化对象中,计划执行一条update语句,再返回这个Customer持久化对象的引用。如果在数据库中不存在这样的Customer持久化对象,就会创建一个新的Customer对象,把customer1游离对象的属性复制到这个新建的Customer对象中,再调用save()方法持久化这个Customer对象,最后返回这个Customer持久化对象的引用。

(3)如果merge()方法的参数customer1为一个临时对象,那么也会创建一个新的Customer对象,把customer1临时对象的属性复制到这个新建的Customer对象中,再调用save()方法持久化这个Customer对象,最后返回这个Customer持久化对象的引用。

从merge()方法的处理流程可以看出,merge()方法返回的customer3是一个持久化对象。参数传入的customer1为游离对象或临时对象,customer1的属性被复制到custome3持久化对象中。程序调用完merge()方法,customer1对象就没有使用价值,可以结束生命周期了,程序接下来可以继续操纵customer3对象。

merge()方法到底把customer1对象的哪些属性复制到customer3持久化对象中呢?主要包括以下内容:

(1)customer1对象的所有值类型的属性。

(2)customer1对象的集合类型属性中的元素。例如,假定customer1对象的orders集合属性中存放了Order对象,以下代码先对orders集合做添加及删除操作。那么merge()方法会对customer3持久化对象的orders集合属性也做相应的添加及删除操作。

customer1.getOrders().add(order1); //加入一个订单
customer1.getOrders().remove(order2); //删除一个订单
……
Customer customer3=(Customer)session.merge(customer1);

在这里插入图片描述

标签:customer1,Customer,EntityManager,持久,读书笔记,JPA,对象,session,merge
来源: https://blog.51cto.com/sunweiqin/2752662