Hibernate NonUniqueObjectException异常:同ID对象会话关联冲突求助
解决Hibernate
NonUniqueObjectException 问题 这个异常的核心原因很明确:你的Hibernate会话中已经存在一个带有相同ID的托管对象,而你现在试图更新另一个不同的实例。咱们拆解下你的代码就能明白:
业务层里,你先通过findCHEMRFacilityMedicalEquipmentById(id)获取了medicalequ对象,这个对象此时已经被Hibernate的当前会话托管了。紧接着你又new了一个updateMed实例,设置了相同的ID,然后调用update方法——这就触发了冲突,因为Hibernate不允许同一个会话里有两个不同的实例对应数据库中同一条记录。
下面给你几个可行的解决方案:
方案1:直接修改托管对象(推荐)
既然medicalequ已经是会话托管的对象,你可以直接修改它的属性,Hibernate会在会话提交时自动执行脏检查并更新数据库,根本不需要显式调用update:
try { final CHEMRFacilityMedicalEquipment medicalequ = m_chemrFacilityMedicalEquipmentManagementBO.findCHEMRFacilityMedicalEquipmentById(id); if (medicalequ.getMetaStatus() == true) { medicalequ.setMetaStatus(false); // 这里不需要调用update,Hibernate会自动处理脏数据更新 return true; } return false; }
方案2:使用merge代替update
如果你确实需要创建新的实例来更新,可以用merge方法,它会把新实例的属性合并到会话中已有的托管对象上;如果会话中没有对应对象,就创建一个新的托管实例:
修改你的DAO层代码,把update换成merge:
try { m_sessionFactory.getCurrentSession().merge(instance); } catch (final DataAccessException _e) { M_LOG.debug("Update object failed:" + _e.toString()); throw new CHEMRDAOException(_e.toString()); } catch (final Exception _e) { M_LOG.debug("Update object failed:" + _e.toString()); throw new CHEMRDAOException(_e.toString()); }
方案3:先 detach 原有对象再更新
如果你坚持要用update,可以先把原来的medicalequ从会话中分离出去,这样会话里就没有同ID的托管对象了:
try { final CHEMRFacilityMedicalEquipment medicalequ = m_chemrFacilityMedicalEquipmentManagementBO.findCHEMRFacilityMedicalEquipmentById(id); final CHEMRFacilityMedicalEquipment updateMed = new CHEMRFacilityMedicalEquipment(); if (medicalequ.getMetaStatus() == true) { // 先将原有对象从会话中分离 m_sessionFactory.getCurrentSession().evict(medicalequ); updateMed.setId(medicalequ.getId()); updateMed.setMetaStatus(false); m_chemrFacilityMedicalEquipmentManagementBO.updateCHEMRFacilityMedicalEquipment(updateMed); return true; } return false; }
个人最推荐方案1,因为它最符合Hibernate的工作机制,代码也更简洁高效。
内容的提问来源于stack exchange,提问作者phani kumar
相关产品推荐
相关产品推荐

