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

来源:互联网 发布:centos源码编译安装 编辑:程序博客网 时间:2024/06/09 23:33

以前也遇到过这个异常,当时也不知道怎么做就上网查,这回又再一次的遇到了这个异常了,决心要追根溯源,找到问题的原点。

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

这个错误的意思就是2个不同的对象关联到了同一个标志位,也就是说在一个session中存在2个对象,但这 2个对象的标志位是相同的比如2个对象的 id值是一样的 而这又是数据库的唯一主键 ,在做更新操作的时候就出现冲突了,因为Hibernate不知道到底要去更新哪个对象 ,所以就报这个异常了。

 

在网上搜索给出了这样的几个答案

  解决方法一:session.clean()
  PS:如果在clean操作后面又进行了saveOrUpdate(object)等改变数据状态的操作,有可能会报出"Found two representations of same collection"异常。
  解决方法二:session.refresh(object)
  PS:当object不是数据库中已有数据的对象的时候,不能使用session.refresh(object)因为该方法是从hibernate的session中去重新取object,如果session中没有这个对象,则会报错所以当你使用saveOrUpdate(object)之前还需要判断一下。
  解决方法三:session.merge(object)
  PS:Hibernate里面自带的方法,推荐使用。
我的分析:我们通常在程序中这样编写时导致这个异常出现的,首先是我们获取从页面传过来的对象,我们叫它vo(view object),然后我们接着调用hibernate的方法查询数据库获取和这个vo主键一样的实体类,我们叫它po,然后我们把po里的属性获取到赋值到vo属性里,最后我们调用了hibernate的方法更新vo,这时就报这个异常了。这个出现的原因就是hibernate的session的缓存中同时存在vo对象和po对象,并且他们俩的ID是一样的,所以hibernate不知道更新那个了。
最后解决方法是,我们操作的是从数据库中查询出来的那个实体类po,把要更新的属性调用po实体类里的set方法复制,这样在hibernate的session中就会一直保持一个实体对象,不要完全new一个对象,也不要把vo赋值给实体类,这样还会报这个错的。因为给复制或new一个对象后,在hibernate的session中又会有两个对象了。

 


原创粉丝点击