先说点题外话,下面这段代码让我觉得很惊讶:
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
分享到:
相关推荐
Hibernate中session的merge以及update方法
### Hibernate merge、update与saveOrUpdate方法的区别 在Hibernate框架中,`merge`、`update`与`saveOrUpdate`这三个方法都是用于更新或保存实体对象到数据库中的,但它们之间存在着重要的区别,这些区别主要体现...
在Java的持久化框架Hibernate中,管理对象与数据库之间的交互是通过一系列的方法完成的,其中包括`save()`, `saveOrUpdate()`, `persist()`, `merge()`, 和 `update()`。这些方法各有其特点和适用场景,理解它们的...
非常经典的SQL经验,适合于数据库初学者及长期从事软件开发者
在SQL语言中,`MERGE INTO`语句是一种强大的工具,用于合并两个数据集,它允许根据特定条件将数据从一个源(通常是...在实际工作中,我们需要根据具体需求调整`MERGE INTO`的条件和操作,确保数据的一致性和完整性。
在Oracle 9i版本中,Merge Into 的引入使得开发者能够同时执行更新(UPDATE)和插入(INSERT)操作,而到了Oracle 10g及后续版本,这一功能得到了进一步增强,提供了更丰富的条件选择和操作选项。 ### 知识点详述:...
首先,需要使用Oracle 9i及其以后版本支持的merge into语句,该语句可以实现insertOrUpdate的功能。然后,使用Mybatis的动态SQL语法foreach循环插入,待插入的实体bean的List通过查询数据库dual形成表。foreach的 ...
3. **区别于SaveOrUpdate**:虽然`merge()`和`saveOrUpdate()`都可以用来保存或更新实体对象,但它们在实现机制上有所不同。`merge()`会先尝试查找具有相同标识符的对象,如果找到则更新,未找到则插入,而`...
Merge 函数的使用方式有三种:只更新不插入、只插入不更新和既插入也更新。 Merge 函数的基本用法 Merge 函数的基本语法结构为: ```sql MERGE INTO 目标表 USING 来源表 ON (条件) WHEN MATCHED THEN 更新操作 ...
在Oracle 9i中,`MERGE INTO`语句首次被引入,它允许在同一语句中执行`INSERT`和`UPDATE`操作。到了Oracle 10g,这个功能得到了进一步增强,使其更加强大和灵活。通过`MERGE INTO`,可以基于源表和目标表之间的匹配...
`MERGE`语句是数据库操作中一种非常强大的工具,它结合了`INSERT`, `UPDATE`, 和 `DELETE`的功能,可以一次性处理数据的插入、更新和删除操作,尤其是在数据同步或数据仓库场景中非常实用。本文将详细解释`MERGE`...
1. **UPDATE或INSERT子句成为可选项**:与Oracle 9i不同的是,在Oracle 10g中,`MERGE`语句允许用户只指定`UPDATE`或`INSERT`中的任意一个操作。 2. **支持WHERE子句**:在`UPDATE`和`INSERT`子句后可以添加`WHERE`...
3. **理解From和To的意义**:在Merge操作中,`from` 和 `to` 容易引起混淆。实际上,`from` 可以理解为原始版本,而 `to` 则是最终状态。在Merge时,`from` 和 `to` 之间的差异会被计算出来,并应用到 `from` 所代表...
`MERGE`语句在Oracle数据库中是一种非常实用的DML操作,它结合了`INSERT`、`UPDATE`和`DELETE`的功能,使得在处理数据时更加高效且简洁。这个语句自Oracle 9i版本开始引入,主要用于解决在两个数据源之间进行有条件...
在Oracle数据库中,`MERGE INTO`语句是一种强大的数据操作工具,它允许你在一个步骤中执行更新(UPDATE)和插入(INSERT)操作,从而提高了数据处理的效率和灵活性。这个命令尤其适用于需要同步两个表的数据时,比如...
最显著的变化之一是 `UPDATE` 和 `INSERT` 操作不再是必需的,用户可以根据需求选择性地使用这些子句。此外,`MERGE` 语句还可以结合 `DELETE` 功能,允许在同一步骤中更新现有记录的同时删除旧记录。 #### 五、...
在 Oracle 数据库中,Merge Into 语句是一种非常有用的功能,它主要用来合并 update 和 insert 语句,即用一个表中的数据来修 改或插入到另一个表中。Merge Into 语句的主要原则是“有则更新,无则插入”。 Merge ...
update_installer.exe文件表明Sublime Merge具有自动更新机制,保证用户能够及时获取最新版本和修复。changelog.txt文件则记录了软件的更新日志,让用户了解每次更新带来的新特性和改进。 **8. 与Sublime Text的...
在数据库操作中,`MERGE`语句是一种非常强大的工具,它结合了`UPDATE`和`INSERT`的功能,允许我们根据源表中的数据更新目标表中的记录,如果源表中的记录在目标表中不存在,则可以插入新记录。此功能非常适合于数据...