>>分享孙卫琴的Java技术专稿和著作 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 20611 个阅读者 刷新本主题
 * 贴子主题:  【持久化专题】EntityManager和Session的merge()方法详解 回复文章 点赞(0)  收藏  
作者:sunweiqin    发表时间:2021-05-05 07:53:54     消息  查看  搜索  好友  邮件  复制  引用

本文参考《精通JPA与Hibernate:Java对象持久化技术详解》,作者:孙卫琴,清华大学出版社出版

   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);

点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

            

----------------------------
原文链接:https://blog.51cto.com/sunweiqin/2752662

程序猿的技术大观园:www.javathinker.net





[这个贴子最后由 admin 在 2021-10-09 10:44:41 重新编辑]
  Java面向对象编程-->集合(上)
  JavaWeb开发-->Web运作原理(Ⅱ)
  JSP与Hibernate开发-->JPA API的高级用法
  Java网络编程-->对象的序列化与反序列化
  精通Spring-->Vue Router路由管理器
  Vue3开发-->Vue简介
  【Vue.js技术专题】Vue组件的单向数据流
  【Vue.js技术专题】分割setup()函数
  【Vue.js技术专题】自定义指令范例:v-drag指令
  【Spring专题】用Spring框架进行文件下载
  【Spring专题】把Model的数据存放在session范围
  【Vue专题】Vue组件的CSS过渡模式
  【持久化专题】映射一对多双向关联关系
  【持久化专题】JPA API的基本用法
  【持久化专题】FetchType.LAZY延迟检索策略
  【持久化专题】通过JPA API调用存储过程
  【Java网络编程专题】创建基于SSL的安全服务器和安全客户的范...
  【JavaWeb专题】在JavaWeb应用中对客户请求的异步处理
  【Java基础编程专题】Java继承的利弊和使用原则
  【Java基础编程专题】为什么说:继承关系最大的弱点就是打破...
  IT培训课、视频教程和书本之PK
  更多...
 IPIP: 已设置保密
楼主      
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。