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

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

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中又会有两个对象了。

 


发布了21 篇原创文章 · 获赞 24 · 访问量 22万+
展开阅读全文

different object with the same identifier value wa

11-18

INFO com.c35.paris.dao.impl.UserDAOImpl.modifyById(UserDAOImpl.java:114) - modifyById method is running! ERROR com.c35.paris.dao.impl.UserDAOImpl.modifyById(UserDAOImpl.java:121) - org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.c35.paris.vo.User#8aa3b3671d8ebd4c011d8ec457980003] org.hibernate.HibernateException: 修改数据出错!a different object with the same identifier value was already associated with the session: [com.c35.paris.vo.User#8aa3b3671d8ebd4c011d8ec457980003] [b]问题补充:[/b] INFO com.c35.paris.dao.impl.UserDAOImpl.modifyById(UserDAOImpl.java:114) - modifyById method is running! ERROR com.c35.paris.dao.impl.UserDAOImpl.modifyById(UserDAOImpl.java:121) - org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.c35.paris.vo.User#8aa3b3671d8ebd4c011d8ec457980003] org.hibernate.HibernateException: 修改数据出错!a different object with the same identifier value was already associated with the session: [com.c35.paris.vo.User#8aa3b3671d8ebd4c011d8ec457980003] 怎么修改, 是下面的方法错了么? public boolean modifyById(String id, Object o)throws Exception { boolean flag=false; log.info("modifyById method is running!"); Transaction tran = null; try { tran = session.beginTransaction(); this.session.update(o); flag=true; } catch (HibernateException e) { log.error(e.toString()); flag=false; throw new HibernateException("修改数据出错!"+e.getMessage()) ; } return flag; } [b]问题补充:[/b] INFO com.c35.paris.dao.impl.UserDAOImpl.modifyById(UserDAOImpl.java:114) - modifyById method is running! ERROR com.c35.paris.dao.impl.UserDAOImpl.modifyById(UserDAOImpl.java:121) - org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.c35.paris.vo.User#8aa3b3671d8ebd4c011d8ec457980003] org.hibernate.HibernateException: 修改数据出错!a different object with the same identifier value was already associated with the session: [com.c35.paris.vo.User#8aa3b3671d8ebd4c011d8ec457980003] <strong>问题补充:</strong> 怎么修改, 是下面的方法错了么? public boolean modifyById(String id, Object o)throws Exception { boolean flag=false; log.info("modifyById method is running!"); Transaction tran = null; try { tran = session.beginTransaction(); this.session.update(o); flag=true; } catch (HibernateException e) { log.error(e.toString()); flag=false; throw new HibernateException("修改数据出错!"+e.getMessage()) ; } return flag; } 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览