Hibernate中merge()方法解析
创始人
2024-06-08 00:11:08
0

本文教你简单学会Hibernate merge() add操作,具体的实现过程如下:

背景:
◆Account 和 Group 两个对象,设置了双向的many-to-many关系,lazy=true

◆不使用open session in view 模式

◆不使用hibernate二级缓

◆考虑web应用场景,设置account和group关联时,只需要group和account的id就够了。

◆数据库中存在两个group: 1.administrators, 2.engineers而po对象中,group信息为:1.invalid, 2.any one

代码A:

  1. Account account = (Account) getHibernateTemplate().merge(po);     
  2. Long id = account.getId();     
  3. System.out.println("\tGet obj after added in dao start ...");     
  4. Account readAccount = (Account) getHibernateTemplate().get(     
  5.     Account.class, id);     
  6. System.out.println("\tGet obj after added in dao end ...");     
  7. System.out.println("\tIs po==readAccount ? " + (po == readAccount));     
  8. System.out.println("\tShow detai of po: " + po.toDetailString());     
  9. System.out.println("\tShow detai of readAccount: " + readAccount.toDetailString());   
  10.  

其中,为po设置了两个group 输出结果:

  1. Hibernate: select ... from SYS_GROUPS where ID=?     
  2. Hibernate: select ... from SYS_GROUPS where ID=?     
  3.     Get obj after added in dao start ...     
  4.     Get obj after added in dao end ...     
  5.     Is po==readAccount ? false    
  6.     Show detai of po: Account[0.account_22, groups[2.any one 1.invalid ]]     
  7.     Show detai of readAccount: Account[22.account_22, groups[2.engineers 1.administrators ]]     
  8. Hibernate: insert into SYS_ACCOUNTS (...) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)     
  9. Hibernate: insert into SYS_GROUP_MEMBER (ACCOUNT_ID, GROUP_ID) values (?, ?)     
  10. Hibernate: insert into SYS_GROUP_MEMBER (ACCOUNT_ID, GROUP_ID) values (?, ?)   
  11.  

代码B:

  1. Long id = (Long) getHibernateTemplate().save(po);     
  2. System.out.println("\tGet obj after added in dao start ...");     
  3. Group group = (Group)getHibernateTemplate().get(Group.class,new Long(1));     
  4. System.out.println("\tGroup detai:" + group.toString());     
  5. Account readAccount = (Account) getHibernateTemplate().get(     
  6.     Account.class, id);     
  7. System.out.println("\tGet obj after added in dao end ...");     
  8. System.out.println("\tIs po==readAccount ? " + (po == readAccount));     
  9. System.out.println("\tShow detai of po: " + po.toDetailString());     
  10. System.out.println("\tShow detai of readAccount: "    
  11.     + readAccount.toDetailString());     
  12.     
  13. getHibernateTemplate().merge(readAccount);     
  14. Account readAgain = (Account) getHibernateTemplate().get(Account.class,     
  15.     id);     
  16. System.out.println("\tIs po==readAgain ? " + (readAgain == po));     
  17. System.out.println("\tIs readAgain== readAccount? "    
  18.     + (readAgain == readAccount));     
  19. System.out.println("\tShow detai again: " + readAgain.toDetailString());    
  20.  

输出结果:

  1.     Get obj after added in dao start ...     
  2. Hibernate: select ... from SYS_GROUPS where ID=?     
  3.     Group detai:Group 1. administrators     
  4.     Get obj after added in dao end ...     
  5.     Is po==readAccount ? true    
  6.     Show detai of po: Account[27.account_27, groups[1.invalid 2.any one ]]     
  7.     Show detai of readAccount: Account[27.account_27, groups[1.invalid 2.any one ]]     
  8. Hibernate: select ... from SYS_GROUPS where ID=?     
  9.     Is po==readAgain ? true    
  10.     Is readAgain== readAccount? true    
  11.     Show detai again: Account[27.account_27, groups[1.administrators 2.engineers ]]     
  12. Hibernate: insert into SYS_ACCOUNTS (...) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)     
  13. Hibernate: insert into SYS_GROUP_MEMBER (ACCOUNT_ID, GROUP_ID) values (?, ?)     
  14. Hibernate: insert into SYS_GROUP_MEMBER (ACCOUNT_ID, GROUP_ID) values (?, ?)    
  15.  

结论:

1. Hibernate merge()方法会导致执行查询group对象的select语句,在调用merge()命令时立即执行(条件:目标group对象没有被缓存)

2. 无论Hibernate merge()或save()方法,insert语句都在***执行,并非在调用相应命令时立即执行

3. 直接调用merge()方法时,会返回一个新的instance,原po保持不变

4. save()之后,po中的group对象并没有被关联到session,因此查询group(id=1)会触发select语句

5. save()之后,po对象被关联到session,再次查询,不会触发select语句,并且不会检查group对象是否被关联到session

6. save()之后再调用merge,返回的是同一个instance,但其关联group对象会被更新

如果在add一个对象之后,如果存在关联对象,并且需要再同一个hibernate session中进行回显,则建议使用Hibernate merge()方法。

参考:
    Hibernate Session.merge() javadoc
    open session in view 模式

【编辑推荐】

  1. 浅析Hibernate延迟加载
  2. Hibernate属性简单分析
  3. Struts-Spring-Hibernate案例
  4. Hibernate Sessin接口常用方法
  5. Hibernate事务全面介绍

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...
《非诚勿扰》红人闫凤娇被曝厕所... 【51CTO.com 综合消息360安全专家提醒说,“闫凤娇”、“非诚勿扰”已经被黑客盯上成为了“木...
2012年第四季度互联网状况报... [[71653]]  北京时间4月25日消息,据国外媒体报道,全球知名的云平台公司Akamai Te...