工作四年多了,以前也用过hibernate中的merge方法,但一直也没深入了解过,这次研究了下,记录下来,方便自己以后查阅:
1、调用merge(obj)方法后,obj仍然是detatch状态,而不是像save,或者update方法,直接变为Persistent状态,但在大部分功能上相当于saveorupdate()方法;
2、需要注意的是,先看下面例子:
Session session = this.getSession();
Transaction tr = session.beginTransaction();
User exituser = (User)session.get(User.class, new Integer(1));
tr.commit();
session.close();
session = getSession();
tr = session.beginTransaction();
User exituser2 = (User)session.get(User.class, new Integer(1));
session.update(exituser);
tr.commit();
session.close();
运行上面的代码,hibernate给我们报了一个错误:a different object with the same identifier value was already associated with the session。意思是,在session缓存中以两个标识相同的对象,这是不可以的。那么,吧update改成merge会怎么样呢?改为merge后,一切OK,运行正常,其实merge在执行更新之前会将两个标识符相同的对象进行合并,具体合并的方向是向exituser2合并,exituser还是detatch状态,exituser2还是persistent状态。
3、还要注意的是,merge方法是使用代理对象,所以必须在事务管理中调用
注意:merge方法在执行之前都回去缓存中找是不是有相应的记录,也就是会有一条select语句,执行改语句的目的是为了判断该对象是否被修改了。而update就不管这些,直接就一条update语句。
1、调用merge(obj)方法后,obj仍然是detatch状态,而不是像save,或者update方法,直接变为Persistent状态,但在大部分功能上相当于saveorupdate()方法;
2、需要注意的是,先看下面例子:
Session session = this.getSession();
Transaction tr = session.beginTransaction();
User exituser = (User)session.get(User.class, new Integer(1));
tr.commit();
session.close();
session = getSession();
tr = session.beginTransaction();
User exituser2 = (User)session.get(User.class, new Integer(1));
session.update(exituser);
tr.commit();
session.close();
运行上面的代码,hibernate给我们报了一个错误:a different object with the same identifier value was already associated with the session。意思是,在session缓存中以两个标识相同的对象,这是不可以的。那么,吧update改成merge会怎么样呢?改为merge后,一切OK,运行正常,其实merge在执行更新之前会将两个标识符相同的对象进行合并,具体合并的方向是向exituser2合并,exituser还是detatch状态,exituser2还是persistent状态。
3、还要注意的是,merge方法是使用代理对象,所以必须在事务管理中调用
注意:merge方法在执行之前都回去缓存中找是不是有相应的记录,也就是会有一条select语句,执行改语句的目的是为了判断该对象是否被修改了。而update就不管这些,直接就一条update语句。