先说点题外话,下面这段代码让我觉得很惊讶:
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方法的区别
非常经典的SQL经验,适合于数据库初学者及长期从事软件开发者
hibernate save()方法... 假如两个实体之间有关系(例如employee表和address表有一对一关系),如果在没有事务的情况下调用这个方法保存employee这个实体,除非调用flush()这个方法,否则仅仅employee实体会被保存。
Merge into写法,含两种,带实例说明
当ID在数据库中能找到的时候,update与merge的执行效果都是更新数据,发出update语句; 如果没有设置ID的话,则这个对象就当作瞬态处理: 用update的话,由于没有ID,所以会报异常,merge此时则会保存数据,根据ID...
oracle merge into的使用,开发必备的。
MERGE语句是Oracle9i新增的语法,用来合并UPDATE和INSERT语句。 通过MERGE语句,根据一张表或多表联合查询的连接条件对另外一张表进行查询,连接条件匹配上的进行UPDATE,无法匹配的执行INSERT。这个语法仅需要一次...
在 Oracle 数据库中,Merge Into 语句是一种非常有用的功能,它主要用来合并 update 和 insert 语句,即用一个表中的数据来修 改或插入到另一个表中。Merge Into 语句的主要原则是“有则更新,无则插入”。 Merge ...
快速浏览一、append与... update方法(a)三个特点(b)例子三、concat方法四、merge与join1.merge函数2. join函数五、问题与练习阶段总结Reference #从清华镜像拉装1.0.3版本的Pandas !pip install -i https://pypi.t
它在SQL Server 2008被引入,它能将Insert,Update,Delete简单的并为一句。MSDN对于Merge的解释非常的短小精悍:”根据与源表联接的结果,对目标表执行插入、更新或删除操作。 MERGE 目标表 USING 源表 ON 匹配...
在Oracle 9i R2版中引入的MERGE语句通常被称作“更新插入”(upsert),因为使用MERGE可以在同一个步骤中更新(update)并插入(insert)数据行。。。。。。
MERGE是Oracle9i新增的语法,用来合并UPDATE和INSERT语句。通过MERGE语句,根据一张表(原数据表,source table)或子查询的连接条件对另外一张(目标表,target table)表进行查询,连接条件匹配上的进行UPDATE,...
根据表结构生成打印出根据主键update的语句
实际项目中遇到的问题总结:数据量百万级,千万级。Oracle中update语句的优化,一共四种方案,工作中遇到该类问题可以参考。
内容概览1 append与assign1.1append方法1.2 assign方法2 combine与update2.1 combine方法2.2 update方法3 concat方法4 merge与join4.1 merge函数4.2 join函数5 问题与练习5.1 问题5.2 练习练习一:公司员工信息练习...
在获取update操作的返回值时遇到了一个问题,似乎 Mybatis 进行 update 操作得到的 int 返回值并不是影响的行数,下面通过本文给大家分享Mybatis Update操作返回值问题,需要的朋友参考下吧
作用:判断B表和A表是否满足ON中条件,如果满足则用B表去更新A表,如果不满足,则将B表数据插入A表但是有很多可选项,如下: 1.正常模式 2.只update或者只insert 3.带条件的update或带条件的insert 4.
Pybigquery合并支持 免责声明:这只是我在玩SQLAlchemy的自定义SQL功能。 使用后果自负,等等。 推介会 该存储库(旨在)将功能添加到... WhenMatched ( update ( target ). values ({ target . c . t2 : source . c .
mysql “ON DUPLICATE KEY UPDATE” 语法如果在INSERT语句末尾指定了ON DUPLICATE KEY UPDATE,并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值,则在出现重复值的行执行UPDATE;如果不会导致唯一值列...