zoukankan      html  css  js  c++  java
  • Hiberate 更新时报错 a different object with the same identifier value was already associated with the session

    使用的是Hibernate框架,Service类里有这样一个方法:

     1 public boolean saveOrUpdateTroop(TroopsInfo o, Boolean save) {
     2         if (save) {
     3             Map<String, Boolean> existeds = this.troopsDAO.getExisted();
     4             Boolean flag = existeds.get(o.getName());
     5             if (flag != null && flag) {
     6                 return false;//存在相同名称的应急队伍
     7             }
     8             this.troopsDAO.saveOrUpdate(o);
     9         }else {//更新
    10             TroopsInfo old = this.troopsDAO.findUniqueBy("id", o.getId());
    11             if (old.getName().equals(o.getName())) {
    12                 //同步更新到应急组织下的人员信息
    13                 this.troopsDAO.saveOrUpdate(o);
    14             }else {//需要检查姓名是重复
    15                 Map<String, Boolean> existeds = this.troopsDAO.getExisted();
    16                 Boolean flag = existeds.get(o.getName());
    17                 if (flag != null && flag) {
    18                     return false;//存在相同名称的应急队伍
    19                 }
    20                 this.troopsDAO.saveOrUpdate(o);
    21             }
    22             this.emergencyPersonDAO.updateEPerson(o.getId(), o.getName(), o.getContact());
    23         }
    24         
    25         return true;
    26     }

    实际执行的时候会在第13行(根据前面的条件跳转到这里)报错:a different object with the same identifier value was already associated with the session。

    解决方法:后来改成merge()方法就可以了。

    原因:从上下文来看,这里在保存前先去数据库中取了一次数据(放session缓存里),然后在保存的。根据hibernate的官方文档里,这样描述update的:

    Update the persistent instance with the identifier of the given detached instance,if there is a persistent instance with the same identifier,an exception is thrown.所以上面的错误就很好得被解释了。

    同样,hibernate的merge方法的解释是:copy the state of the given object onto the persistent object with the same identifier,if there is no persistent instance currently associated with the session,

    it will be loaded...

    还有一种解决方法:refresh()或者clean(),但是会报其他的错误,所以不建议用。

  • 相关阅读:
    《Advanced Bash-scripting Guide》学习(四):一个显示时间日期登录用户的脚本
    《Advanced Bash-scripting Guide》学习(三):自删除脚本和自读取内容的脚本
    51nod 1005 大数加法
    51nod1019 逆序数
    scoi2010 幸运数字
    COGS 513 八
    [HNOI2006]超级英雄Hero
    NOIP2010 关押罪犯
    [Scoi2010]游戏
    bzoj 2820: YY的GCD
  • 原文地址:https://www.cnblogs.com/emmalai/p/4180798.html
Copyright © 2011-2022 走看看