a different object with the same identifier value was already associated with th

问题

今天做hibernate开发出了一个这样的问题

a different object with the same identifier value was already associated with the session

 

明白几个session对象

首先我们要知道原因是在hibernate中同一个session里面有连个相同的标识,但是他们两个确实不同的实体,在这时运行saveOrUpdate操作的时候就报了这个错误

为什么会报这个错呢,首先我们要明白session的几个使用

save()或 saveOrUpdate()是将瞬时对象与数据库相关联,并将数据对应的插入数据库中,此时该瞬时对象转变成持久化对象。

delete()方法将持久对象就变成瞬时对象, 因数据库中的对应数据已被删除,该对象不再与数据库的记录关联。

close()或clear()、evict()之后,持久对象变成脱管对象,此时持久对象会变成脱管对象,此时该对象虽然具有 数据库识别值,但它已不在HIbernate持久层的管理之下。

merge():但当我们使用merge的时候,把处理自由态的持久对象A的属性copy到session当中处于持久态的持久的属性中,执行完成后原来是持久状态还是持久态,而我们提供的A还是自由态

 

了解我的流程:

我的程序的流程是这样的,首先A表示主表,B表示从表,A和B是一对多的关系

由于业务的需求,我先对A表执行的添加(或者修改--------[在执行修改的时候先查询A对象的操作,那么此时B对象也会通过级联查询出来]),通过添加后返回的对象,对B表中存在的此对象进行删除操作,最后对B表执行添加然后事务才开始执行commit的方法

如果我在执行删除之后没有执行添加是不会报任何错误的,为何执行了saveOrUpdate之后就出错了呢

首先我们要明白这三个操作时在事务中执行的

(1)delete()执行之后其实数据和session中的对象都存在,因为没有执行事务的commit方法

(2)在saveOrUpdate()中执行对象添加的时候,在session的对象中已经存在了当前对象的相同标识的对象,那么对象无法保存进去肯定会出错的

 

解决办法:

(1)在delete()之后执行evcit()方法,将此对象变成脱管状态,那么次对象就不会在session中了,再次执行saveOrUpdate()的时候就不会存在相同的标识了,自然也就不会报错了!当然有人肯定会问,如果我想在saveOrUpdate()的之前再次使用那个脱管对象呢,那么我们只需要将此对象再次放到session中就可以,比如执行get(),load()方法,不过应该没有这么变态的业务逻辑吧!

(2)当然除了使用evcit()方法将delete()中的对象变成脱管对象外,我们还可以在saveOrUpdate()中做操作,那么就是用merge()方法,由A的说我们,我们就明白了,即使在delete()的时候我们没有执行evcit(),那么在执行merge()方法的时候,即使session中存在相同标志的持久对象,merge()会用当前对象替换掉session中的持久对象,一切就ok了

猜你喜欢

转载自rosydawn.iteye.com/blog/2218884