merge和update的区别

先说点题外话,下面这段代码让我觉得很惊讶:
		session.beginTransaction();
User usr = (User)session.get(User.class, new Long(1));
usr.setNickName("c");
session.getTransaction().commit();
session.close();

基本上已经简单的不能再简单了,但让我惊讶的是:我并没有现实的调用session.update之类的东西,居然给我自动更新了...实在想不明白为什么。
[color=red]答案:update操作的是在脱管状态的对象
而flush是操作的在持久状态的对象
[/color]


题外话说了不少,切入正题吧:每一个session中同一个oid只能有一个持久态的对象与其相对应,如果过对应该oid该对象有多个对象,则会引发异常:NonUniqueObjectException
比如说下面这个例子:

private void doMerge() {
User usr = new User();
usr.setOid((long)1);
usr.setNickName("c++");
Session session2 = HibernateSessionFactory.getSessionFactory().openSession();
session2.beginTransaction();
User usr2 = (User)session2.load(User.class, new Long(1));
usr2.setNickName("covex");
//User usr3 = (User)session2.merge(usr);
session2.update(usr);
session2.getTransaction().commit();
session2.close();
}

在session2.update(usr)的时候,usr2本身就是持久态对象,而usr是游离态对象,而二者的oid一致,因此被session认为有第二个对象与同一个oid相关联因此会出现问题。解决方案采用merge.merge会把传入对象的知赋给改session对应的持久化对象,而原来的作为参数的对象,保持游离态状态不变。

private void doMerge() {
User usr = (User)session.get(User.class, new Long(1));
session.close();

usr.setNickName("456");

Session session2 = HibernateSessionFactory.getSessionFactory().openSession();
session2.beginTransaction();
User usr2 = (User)session2.load(User.class, new Long(1));
User usr3 = (User)session2.merge(usr);
System.out.println(usr2 == usr3);//true。这两个引用指向同一个对象。
usr2.setNickName("covex");
session2.update(usr2);//usr2还是处于持久化状态,因此可以继续update操作
session2.getTransaction().commit();
session2.close();

}

[color=red]
参考内容:
http://www.blogjava.net/dreamstone/archive/2007/07/29/133071.html
http://caterpillar.onlyfun.net/Gossip/HibernateGossip/Session.html[/color]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值