使用的是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(),但是會報其他的錯誤,所以不建議用。