一、先貼上網絡上摘的文章
1、a different object with the same identifier value was already associated with the session。
錯誤原因:在hibernate中同一個session裡面有瞭兩個相同標識但是是不同實體。
解決方法一: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裡面自帶的方法,推薦使用。
二、 我的分析
背景知識
DocType 裡面有一個WebSite對象屬性
錯誤代碼
[java] /**
* 刪除單條記錄
*
* @param id 用於刪除的記錄的id
* @return 成功刪除的記錄數
*/
public void delete(Website website) throws Exception {
DocType docType = getDocTypeBS().getDocTypeByCode(ROOT, website.getId());
if (docType != null) {
Set<DocType> docTypeSet = docType.getChildren();
if (docTypeSet != null && docTypeSet.size() > 0) {
throw new Exception("此站點下有子欄目,不能刪除!");
} else {
getDocTypeBS().delete(docType);
getDao().delete(website);
}
}
}
/**
* 刪除單條記錄
*
* @param id 用於刪除的記錄的id
* @return 成功刪除的記錄數
*/
public void delete(Website website) throws Exception {
DocType docType = getDocTypeBS().getDocTypeByCode(ROOT, website.getId());
if (docType != null) {
Set<DocType> docTypeSet = docType.getChildren();
if (docTypeSet != null && docTypeSet.size() > 0) {
throw new Exception("此站點下有子欄目,不能刪除!");
} else {
getDocTypeBS().delete(docType);
getDao().delete(website);
}
}
}
修正代碼
[java] /**
* 刪除單條記錄
*
* @param id 用於刪除的記錄的id
* @return 成功刪除的記錄數
*/
public void delete(Website website) throws Exception {
DocType docType = getDocTypeBS().getDocTypeByCode(ROOT, website.getId());
if (docType != null) {
Set<DocType> docTypeSet = docType.getChildren();
if (docTypeSet != null && docTypeSet.size() > 0) {
throw new Exception("此站點下有子欄目,不能刪除!");
} else {
//此處要註意,刪除時不能傳入參數的website對象,因為上面查出來的docType裡面級聯瞭此site對象,再傳入參數時會在session緩存中會出現兩個主鍵相同的實體www.aiwalls.com
getDao().delete(docType.getSite());
getDocTypeBS().delete(docType);
}
}
}
/**
* 刪除單條記錄
*
* @param id 用於刪除的記錄的id
* @return 成功刪除的記錄數
*/
public void delete(Website website) throws Exception {
DocType docType = getDocTypeBS().getDocTypeByCode(ROOT, website.getId());
if (docType != null) {
Set<DocType> docTypeSet = docType.getChildren();
if (docTypeSet != null && docTypeSet.size() > 0) {
throw new Exception("此站點下有子欄目,不能刪除!");
} else {
//此處要註意,刪除時不能傳入參數的website對象,因為上面查出來的docType裡面級聯瞭此site對象,再傳入參數時會在session緩存中會出現兩個主鍵相同的實體
getDao().delete(docType.getSite());
getDocTypeBS().delete(docType);
}
}
}
我的分析
這是由於查詢DocType的時候級聯查出瞭Website,導致Session中已經有瞭此Website實例瞭,再把遊離態的webSite對象傳入就會導致二個ID相同的對象,Hibernate會報錯的.
摘自 張仁陽專欄