六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 33|回复: 0

merge和update的区别

[复制链接]

升级  37.33%

28

主题

28

主题

28

主题

秀才

Rank: 2

积分
106
 楼主| 发表于 2013-1-27 05:00:00 | 显示全部楼层 |阅读模式
先说点题外话,下面这段代码让我觉得很惊讶:
session.beginTransaction();User usr = (User)session.get(User.class, new Long(1));usr.setNickName("c");session.getTransaction().commit();session.close();
基本上已经简单的不能再简单了,但让我惊讶的是:我并没有现实的调用session.update之类的东西,居然给我自动更新了...实在想不明白为什么。
答案:update操作的是在脱管状态的对象
                   而flush是操作的在持久状态的对象



题外话说了不少,切入正题吧:每一个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();}

参考内容:
http://www.blogjava.net/dreamstone/archive/2007/07/29/133071.html
http://caterpillar.onlyfun.net/Gossip/HibernateGossip/Session.html
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表