>>分享孙卫琴的Java技术专稿和著作 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 14925 个阅读者 刷新本主题
 * 贴子主题:  【持久化专题】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应用中访问Web服务
  JSP与Hibernate开发-->持久化层的映射类型
  Java网络编程-->安全网络通信
  精通Spring-->Vue Router路由管理器
  Vue3开发-->Vue组件开发高级技术
  【Vue.js技术专题】命名路由
  【Vue.js技术专题】Vuex中异步操作
  【Spring Cloud Alibaba专题】GateWay的内置断言工厂
  【Spring专题】@ControllerAdvice注解的用法
  【Spring专题】通过JPA API实现Repository接口
  【持久化专题】JPA API的级联操作
  【持久化专题】对象-关系的映射概念
  【Java网络编程专题】用java.net.URL类访问HTTP服务器读取网...
  【Java网络编程专题】用Java套接字访问HTTP服务器读取网页数...
  【Java网络编程专题】异步通道和异步运算结果
  【JavaWeb专题】Tomcat与IIS集成详解
  《大话Java程序设计从入门到精通》写作花絮
  【Java基础编程专题】用static修饰符进行静态导入的作用和语...
  【Java基础编程专题】为什么说:继承关系最大的弱点就是打破...
  IT培训课、视频教程和书本之PK
  更多...
 IPIP: 已设置保密
楼主      
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


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