今天做了个测试,写了个测试用例来看看merge与update时控制台打印出来的日志有什么不一样。实体bean很简单,就id和name两个字段,接下来分别给出以下几种测试情形的控制台日志内容:
[b]1. 数据库记录已存在,更改person的name为一个新的name。 [/b]
[color=brown]merge方法打印出的日志如下: [/color]
Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_ from
person person0_ where person0_.id=?
Hibernate: update person set name=?
where id=?
[color=brown]update方法打印出的日志如下: [/color]
Hibernate: update person set name=?
where id=?
[b]2. 数据库记录已存在,更改person的name和数据库里对应id记录的name一样的值。 [/b]
[color=brown]merge方法打印出的日志如下: [/color]
Hibernate: select person0_.id as id0_0_,
person0_.name as name0_0_ from person person0_ where person0_.id=?
此处相对于第一种情形少了update的动作
[color=brown]update方法打印出的日志如下: [/color]
Hibernate: update person set name=? where id=?
[b]3. 数据库记录不存在。也就是你传的实体bean的ID在数据库没有对应的记录。 [/b]
[color=brown]merge方法打印出的日志如下: [/color]
Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_
from person person0_ where person0_.id=?
Hibernate: insert into person (name) values (?)
如果没有对应的记录,merge会把该记录当作新的记录来插入。
[color=olive]
此处我很疑惑,因为我传得person实体对象里写明了id值的,它为什么还会做插入的动作呢?(如果使用不好,则会在更新时,不会更新而是新增一行记录!!!)
在做更新操作时,在merge之前先要持久化一下?
[/color]
[color=brown]update方法打印出的日志如下: [/color]
Hibernate: update person set name=? where id=?
2009-11-22 20:59:55,359 ERROR [org.hibernate.jdbc.AbstractBatcher] -
Exception executing batch:
org.hibernate.StaleStateException: Batch update
returned unexpected row count from update [0]; actual row count: 0; expected: 1
[b]以下的内容摘抄自网上: [/b]
当我们使用update的时候,执行完成后,我们提供的对象A的状态变成持久化状态。
当我们使用merge的时候,执行完成后,我们提供的对象A还是脱管状态。hibernate或者是new了一个B(此时执行插入操作),或者检索到一个持久对象B(此时执行更新操作),并把我们提供的对象A的所有的值拷贝到这个B,执行完成后B是持久状态,而我们提供的A还是托管状态。
----------------------------------
使用merge方法,如果数据库中有该记录,则更新该记录,如果不存在该记录,则进行insert操作。
使用update的话,会无条件执行update。
也就是说如果数据库中有该记录的话,merge和update是一样的。
但是如果数据库中没有该记录,使用merge执行insert,不会报错,而使用update会报错。
不同之处在于,update可以持久化类,merge不行 --- 重要
---------------------------------------
假设有个Student stu类,session.update(stu),merge也是一样。
不同之处在于,update可以持久化类,merge不行,执行session.merge(stu)之后,stu对象如果之前不是持久化状态,stu对象依然不会被关联到session上。
----------------------------------------
[b]谁懂得hibernate的merge方法?[/b]
我使用merge方法。老是报could not load an entity的异常。
配置文件,一定没有问题。
于是,我写了个junit的单元测试。这个单元测试继承了HibernateDaoSupport,并注入了sessionFactory,并调用
this.getHibernateTemplate.merge 方法,还是could not load an entity.
是我对merge理解有问题,还是其他什么问题?
用update是直接把实体和数据库同步,而是要merge方法时 merge操作的是实体的代理对象,所以我们用它时一定要把它放到事务中执行,否则会报could not load an entity异常,
意思是在:this.getHibernateTemplate().merge(dc);语句前面开启一个事务就OK
=========================================================
理一下思路:(没有验证)
使用merge方法时,
如果存在一个持久化的对象,则执行 update 操作。
如果不存在一个持久化的对象,则进行插入操作。
所以,对象需要先持久化后,再进行 merge() 。这里的持久化不是数据库中是否有这条记录,而是 Hibernate 中数据的状态。如果数据库中存在一条记录,而没有被 Hibernate 持久化,使用 merge() 时,仍然执行的是新增一条记录操作。而不是更新操作。
-
引用:
http://www.cnblogs.com/hyteddy/archive/2011/05/10/2041762.html
[b]1. 数据库记录已存在,更改person的name为一个新的name。 [/b]
[color=brown]merge方法打印出的日志如下: [/color]
Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_ from
person person0_ where person0_.id=?
Hibernate: update person set name=?
where id=?
[color=brown]update方法打印出的日志如下: [/color]
Hibernate: update person set name=?
where id=?
[b]2. 数据库记录已存在,更改person的name和数据库里对应id记录的name一样的值。 [/b]
[color=brown]merge方法打印出的日志如下: [/color]
Hibernate: select person0_.id as id0_0_,
person0_.name as name0_0_ from person person0_ where person0_.id=?
此处相对于第一种情形少了update的动作
[color=brown]update方法打印出的日志如下: [/color]
Hibernate: update person set name=? where id=?
[b]3. 数据库记录不存在。也就是你传的实体bean的ID在数据库没有对应的记录。 [/b]
[color=brown]merge方法打印出的日志如下: [/color]
Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_
from person person0_ where person0_.id=?
Hibernate: insert into person (name) values (?)
如果没有对应的记录,merge会把该记录当作新的记录来插入。
[color=olive]
此处我很疑惑,因为我传得person实体对象里写明了id值的,它为什么还会做插入的动作呢?(如果使用不好,则会在更新时,不会更新而是新增一行记录!!!)
在做更新操作时,在merge之前先要持久化一下?
[/color]
[color=brown]update方法打印出的日志如下: [/color]
Hibernate: update person set name=? where id=?
2009-11-22 20:59:55,359 ERROR [org.hibernate.jdbc.AbstractBatcher] -
Exception executing batch:
org.hibernate.StaleStateException: Batch update
returned unexpected row count from update [0]; actual row count: 0; expected: 1
[b]以下的内容摘抄自网上: [/b]
当我们使用update的时候,执行完成后,我们提供的对象A的状态变成持久化状态。
当我们使用merge的时候,执行完成后,我们提供的对象A还是脱管状态。hibernate或者是new了一个B(此时执行插入操作),或者检索到一个持久对象B(此时执行更新操作),并把我们提供的对象A的所有的值拷贝到这个B,执行完成后B是持久状态,而我们提供的A还是托管状态。
----------------------------------
使用merge方法,如果数据库中有该记录,则更新该记录,如果不存在该记录,则进行insert操作。
使用update的话,会无条件执行update。
也就是说如果数据库中有该记录的话,merge和update是一样的。
但是如果数据库中没有该记录,使用merge执行insert,不会报错,而使用update会报错。
不同之处在于,update可以持久化类,merge不行 --- 重要
---------------------------------------
假设有个Student stu类,session.update(stu),merge也是一样。
不同之处在于,update可以持久化类,merge不行,执行session.merge(stu)之后,stu对象如果之前不是持久化状态,stu对象依然不会被关联到session上。
----------------------------------------
[b]谁懂得hibernate的merge方法?[/b]
我使用merge方法。老是报could not load an entity的异常。
配置文件,一定没有问题。
于是,我写了个junit的单元测试。这个单元测试继承了HibernateDaoSupport,并注入了sessionFactory,并调用
this.getHibernateTemplate.merge 方法,还是could not load an entity.
是我对merge理解有问题,还是其他什么问题?
//单元测试如下
public class MergeTest extends HibernateDaoSupport {
@Test
public void testMerge(){
//获取spring配置
ApplicationContext act = new FileSystemXmlApplicationContext("/WebRoot/WEB-INF/applicationContext.xml");
//注入sesssionFactory
this.setSessionFactory((SessionFactory)act.getBean("sessionFactory"));
//创建一个模拟的DocumentCatalog 数据中已经有个 id = 1的数据
DocumentCatalog dc = new DocumentCatalog();
dc.setId(1);
dc.setName("crying!!!!!");
//我认为,这时候,数据库中的 id = 1的数据,会被update,但是,发生could not load an entity错误。
//数据库映射没有错误,换成update就能顺利更新。
this.getHibernateTemplate().merge(dc);
}
}
用update是直接把实体和数据库同步,而是要merge方法时 merge操作的是实体的代理对象,所以我们用它时一定要把它放到事务中执行,否则会报could not load an entity异常,
意思是在:this.getHibernateTemplate().merge(dc);语句前面开启一个事务就OK
=========================================================
理一下思路:(没有验证)
使用merge方法时,
如果存在一个持久化的对象,则执行 update 操作。
如果不存在一个持久化的对象,则进行插入操作。
所以,对象需要先持久化后,再进行 merge() 。这里的持久化不是数据库中是否有这条记录,而是 Hibernate 中数据的状态。如果数据库中存在一条记录,而没有被 Hibernate 持久化,使用 merge() 时,仍然执行的是新增一条记录操作。而不是更新操作。
-
引用:
http://www.cnblogs.com/hyteddy/archive/2011/05/10/2041762.html