>>分享孙卫琴的Java技术专稿和著作 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 14978 个阅读者 刷新本主题
 * 贴子主题:  【持久化专题】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开发-->自定义JSP标签(Ⅱ)
  JSP与Hibernate开发-->映射对象标识符
  Java网络编程-->XML数据处理
  精通Spring-->Vue组件开发高级技术
  Vue3开发-->Vue组件开发高级技术
  【Java基础编程专题】使用和创建JavaDoc文档
  【Spring专题】用Spring框架进行文件下载
  【Spring专题】RestTemplate类与RESTFul风格的请求
  【Spring专题】@Query注解设定查询语句
  【持久化专题】JPA API的级联操作
  【持久化专题】用orphanRemoval属性映射父子关系
  【持久化专题】映射一对多双向关联关系
  【持久化专题】@Access注解设定Hibernate访问类的属性的方式
  【持久化专题】Spring与Hibernate与JPA的整合
  【Java网络编程专题】异步通道和异步运算结果
  【Java网络编程专题】用Java套接字编写基本的客户/服务器程序
  【持久化专题】通过JPQL查询语句进行批量处理数据
  【持久化专题】比较JPA的EntityManager接口与Hibernate的Ses...
  【JavaWeb专题】在JavaWeb应用中对客户请求的异步处理
  【Java基础编程专题】Java集合的批量操作
  更多...
 IPIP: 已设置保密
树形列表:   
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


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