解决a different object with the same identifier value was already associated with the session错误...
問題場景:
(我要做對象修改,然后保存進數(shù)據(jù)庫)
我通過數(shù)據(jù)庫獲取一個原對象obj;
然后新增了一個修改對象obj1;
然后將obj1.setId(obj.getId());
然后調(diào)用數(shù)據(jù)庫實例對象SESSION.UPDATE(OBJ1);?
? ? ? 數(shù)據(jù)庫報錯,拋出了異常a different object with the same identifier value was already associated with the session。
?
原因就是session再檢測實例化對象時,發(fā)現(xiàn)obj和obj1的ID相同(通過地址去檢測),導(dǎo)致拋出異常,根據(jù)以下解決方法:
buildDevelopers_tDAO.getSessionFactory().getCurrentSession().merge(buildDev_t_after);
即 使用MERGE()方法,而不是使用update()方法;??
另外一種解決方法:
不要使用set()方法去賦ID;
obj = obj1;
obj.setName()
.....(根據(jù)相應(yīng)的修改,去進行賦值)
然后調(diào)用數(shù)據(jù)庫實例對象SESSION.UPDATE(OBJ1);
即不要使用set方法賦ID即可。
?
解決方案:
1、a different object with the same identifier value was already associated with the session。
錯誤原因:在hibernate中同一個session里面有了兩個相同標(biāo)識但是是不同實體。
解決方法一:session.clean()
PS:如果在clean操作后面又進行了saveOrUpdate(object)等改變數(shù)據(jù)狀態(tài)的操作,有可能會報出"Found two representations of same collection"異常。
解決方法二:session.refresh(object)
PS:當(dāng)object不是數(shù)據(jù)庫中已有數(shù)據(jù)的對象的時候,不能使用session.refresh(object)因為該方法是從hibernate的session中去重新取object,如果session中沒有這個對象,則會報錯所以當(dāng)你使用saveOrUpdate(object)之前還需要判斷一下。
解決方法三:session.merge(object)
PS:Hibernate里面自帶的方法,推薦使用。
2、Found two representations of same collection
錯誤原因:見1。
解決方法:session.merge(object)
??? 以上兩中異常經(jīng)常出現(xiàn)在一對多映射和多對多映射中
3、問題情況:使用hibernate來進行對對象的保存操作時,出現(xiàn)了exception,導(dǎo)致數(shù)據(jù)保存不成功,具體報錯如是:
Exception in thread "main" org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session:
使用情況(本人遇到):如果是在保存對象的時候,如果對象有外鍵,則在保存的時候,要根據(jù)外鍵來獲取數(shù)據(jù)庫所對應(yīng)的記錄的對象,之后再set入要保存的的對象中,如果是直接new一個外鍵的對象(外鍵的值在數(shù)據(jù)庫有對應(yīng)的值)再set入保存的對象中的時候,就會報錯:Exception in thread "main" org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session:,這個是因為,在保存的時候,session會檢查在內(nèi)存的外簡單的對象跟你new的對象是否一樣(不是根據(jù)對象的值,而是根據(jù)在內(nèi)存的地址是否一致來比較的),所以new出來的對象是無法跟內(nèi)存里面的對象一致的,因而,會說不同的對象有一樣的id,所以保存數(shù)據(jù)庫的時候就直接根據(jù)外鍵來獲取對應(yīng)的數(shù)據(jù)庫記錄來保存對象,所以這個時候用merge方法還是解決不了問題的。
最后是在查了一下,采用session.merge (object c)代替session.save(object c),即可解決,主要涉及到session.merge ()方法的使用以及session.merge ()跟session.save()、session.update ()方法的區(qū)別,這篇博文詳細說明了問題....
該方法將修改表中記錄,其所需要的實體狀態(tài)為脫管狀態(tài),但是注意,它并不影響調(diào)用方法前后的狀態(tài),也即該實體依然是脫管狀,見例6.4。
例6.4:session.merge ()方法對狀態(tài)的變化
???? public void run() {
????????? //創(chuàng)建UserInfo實例
????????? UserInfo userInfo = new UserInfo();
????????? //使之成為脫管狀態(tài)
????????? userInfo.setId(11112);
????????? userInfo.setName("RW3");
????????? userInfo.setSex("M");
????????? //創(chuàng)建UserInfo實例
????????? UserInfo userInfo2 = new UserInfo();
????????? //使之成為脫管狀態(tài)
????????? userInfo2.setId(11112);
????????? userInfo2.setName("RW4");
????????? userInfo2.setSex("F");
????????? //啟動Session
????????? Session session = HibernateSessionFactory.currentSession();
????????? //啟動事務(wù)
????????? Transaction tx = session.beginTransaction();
????????? //調(diào)用merge方法,此時UserInfo實體狀態(tài)并沒有被持久化
????????? session.merge(userInfo);
????????? //調(diào)用merge方法,此時UserInfo實體狀態(tài)并沒有被持久化
????????? //但是數(shù)據(jù)庫中的記錄被更新了
????????? ①session.merge(userInfo2);
????????? //merge方法與update方法的差別在于針對同樣的操作update方法會報錯
????????? //原因在于update方法使得實體狀態(tài)成為了持久化狀態(tài),而Session中不允許兩個持久化實體有同樣的持久化標(biāo)識
????????? ②//session.update(userInfo);
????????? //session.update(userInfo2);
???????? //以下兩句不會發(fā)送SQL,因為userInfo2不是持久化狀態(tài)的實體
???????? ③userInfo2.setName("RW5");
????????? userInfo2.setSex("M");
????????? //提交事務(wù)
????????? tx.commit();
????????? //關(guān)閉Hibernate Session
????????? HibernateSessionFactory.closeSession();
???? }
針對該段代碼將執(zhí)行如下SQL語句:
Hibernate:
/* ①session.merge(userInfo2)的動作 */
select
??????? userinfo0_.id as id0_0_,
??????? userinfo0_.NAME as NAME0_0_,
??????? userinfo0_.SEX as SEX0_0_,
??????? userinfo0_.roomid as roomid0_0_
??? from
??????? userinfo userinfo0_
??? where
??????? userinfo0_.id=?
Hibernate:
/* ①session.merge(userInfo2)的動作 */
update
??????????? userinfo
??????? set
??????????? NAME=?,
??????????? SEX=?,
??????????? roomid=?
??????? where
??????????? id=?
session.merge()方法會首先發(fā)送一句select語句,去數(shù)據(jù)庫端獲取UserInfo持久化標(biāo)識所對應(yīng)的表記錄;然后自動生成一個持久化狀態(tài)的UserInfo實體,與脫管狀態(tài)的UserInfo實體做比較是否有所改變;一旦發(fā)生了改變,才會發(fā)送update語句執(zhí)行更新。而按執(zhí)行順序,若兩句session.merge()方法針對同一個脫管狀態(tài)的UserInfo實體,那其結(jié)果只會執(zhí)行最后一個session.merge()方法所發(fā)出的update語句。即使執(zhí)行了session.merge()方法,UserInfo實體依然是脫管狀態(tài),因此③userInfo2. setName("RW5")的語句不會同步數(shù)據(jù)庫中的表。
轉(zhuǎn)載于:https://www.cnblogs.com/UUUz/p/9930292.html
總結(jié)
以上是生活随笔為你收集整理的解决a different object with the same identifier value was already associated with the session错误...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 遍历性能
- 下一篇: 用机器指令和汇编指令编程(修改版)