a different object with the same identifier value was already associated with the session 2

這個問題,我把對象賦值爲NULL,也是很好用的.在我的系統中,更新好用了,可是插入不好用了.沒改前,是插入好用,而更新不好用.本來是系統中的問題,可是,catch只是捕捉到,從但是,沒有把log打印出來,找原因實在是難找.在高度數據庫時,最好把異常捕捉中的信息打印出來.org.springframework.orm.hibernate.HibernateSystemException: a different object with the same identifier value was already associated with the session: 4443398, of class: com.onewaveinc.media.cms.entity.SyncImportFolder; nested exception is net.sf.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: 4443398, of class: com.onewaveinc.media.cms.entity.SyncImportFolder
net.sf.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: 4443398, of class: com.onewaveinc.media.cms.entity.SyncImportFolder
at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:852)
at net.sf.hibernate.impl.SessionImpl.saveWithGeneratedIdentifier(SessionImpl.java:790)
at net.sf.hibernate.impl.SessionImpl.save(SessionImpl.java:749)
at org.springframework.orm.hibernate.HibernateTemplate$9.doInHibernate(HibernateTemplate.java:555)
at org.springframework.orm.hibernate.HibernateTemplate.execute(HibernateTemplate.java:363)
at org.springframework.orm.hibernate.HibernateTemplate.save(HibernateTemplate.java:552)
at com.onewaveinc.media.cms.dao.impl.SyncFolderHibernateDao.insertHavaIndex(SyncFolderHibernateDao.java:31)
at com.onewaveinc.media.cms.manager.SyncFolderManager.doImportSyncFolder(SyncFolderManager.java:193)
at com.onewaveinc.media.cms.manager.SyncFolderManager.insertHavaIndex(SyncFolderManager.java:107)
at com.onewaveinc.media.cms.manager.SyncFolderManager.importSyncFolderList(SyncFolderManager.java:607)
at com.onewaveinc.media.cms.web.SyncFolderImportAction.post(SyncFolderImportAction.java:41)
at com.onewaveinc.media.common.web.HttpMethodAction.execute(HttpMethodAction.java:36)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:421)
at com.onewaveinc.media.web.struts.MediaRequestProcessor.processActionPerform(MediaRequestProcessor.java:51)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:226)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1164)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:415)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at org.ajaxanywhere.AAFilter.doFilter(AAFilter.java:41)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at com.onewaveinc.appcommon.security.web.utils.SecurityFilter.doFilter(SecurityFilter.java:89)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at org.springframework.orm.hibernate.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:174)
at com.onewaveinc.media.common.web.SpringHibernateSessionFilter.doFilterInternal(SpringHibernateSessionFilter.java:50)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at com.onewaveinc.media.web.struts.StrutsValidateFilter.doFilter(StrutsValidateFilter.java:38)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at com.onewaveinc.appcommon.utils.web.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:168)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:118)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardEngin.ve.invoke(StandardEngin.ve.java:109)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
at java.lang.Thread.run(Thread.java:534)



a different object with the same identifier value was already associated with the session
一個經典的hibernate錯誤:a different object with the same identifier value was already associated with the session xxxx
hibernate3.0以上使用merge()來合併兩個session中的同一對象
具體到我自己的代碼就是
public Object getDomain(Object obj) {
  getHibernateTemplate().refresh(obj);
  return obj;
  }
  public void deleteDomain(Object obj) {
  obj = getHibernateTemplate().merge(obj);
  getHibernateTemplate().delete(obj);
  }


解決a different object with the same identifier value was already associated with the session錯誤 

這個錯誤我一共遇到過兩次,一直沒有找到很好的解決方案,這個錯誤產生原因相信大家都知道,因爲在hibernate中同一個session裏面有了兩個相同標識但是是不同實體,當這時運行saveOrUpdate(object)操作的時候就會報這個錯誤。呵呵,也許你會說,你這麼說跟沒說沒什麼區別,我承認,呵呵,我不知道具體爲什麼會產生這個錯誤,要不然也不會很久都沒有解決,現在,給出一個臨時的解決方案,給向我一樣,沒有辦法找到根源的人一個能夠繼續執行下去的方法(當然是對的,只是不是從產生原因入手)

其實要解決這個問題很簡單,只需要進行session.clean()操作就可以解決了,但是你在clean操作後面又進行了saveOrUpdate(object)操作,有可能會報出"Found two representations of same collection",我找了很多資料,沒有什麼很好的解釋,其中這篇文章幫助最大[url]http://opensource.atlassian.com/projects/hibernate/browse/HHH-509[/url]。

最後通過session.refresh(object)方法就可以解決了,注意,當object不是數據庫中已有數據的對象的時候,不能使用session.refresh(object)因爲refresh是從hibernate的session中去重新取object,如果session中沒有這個對象,則會報錯所以當你使用saveOrUpdate(object)之前還需要判斷一下

當然這個問題最容易解決的辦法還是使用Hibernate裏面自帶的merge()方法。不過我始終覺得碰到問題就用這種軟件自帶的非常用方法(和saveOrUpdate(),save(),update()相比)感覺十分不爽。

後來我還發現這種錯誤經常出現在一對多映射和多對多映射,請大家在使用一對多和多對多映射的時候要小心一些


Hibernate 疑難異常及處理


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裏面自帶的方法,推薦使用。

2、Found two representations of same collection

  錯誤原因:見1。

  解決方法:session.merge(object)

以上兩中異常經常出現在一對多映射和多對多映射中


a different object with the same identifier value was already associated with the session
一個經典的hibernate錯誤:a different object with the same identifier value was already associated with the session xxxx
hibernate3.0以上使用merge()來合併兩個session中的同一對象
具體到我自己的代碼就是
public Object getDomain(Object obj) {
  getHibernateTemplate().refresh(obj);
  return obj;
  }
  public void deleteDomain(Object obj) {
  obj = getHibernateTemplate().merge(obj);
  getHibernateTemplate().delete(obj);
  }
====================我是分割線===================
其實我的解決辦法是把obj給重新merge一下,注意紅字部分
public Serializable save(Object persistentObject) throws DaoException {
  try {
        
  Session session = this.openSession();
  beginTransaction();
  persistentObject = session.merge(persistentObject);
  Serializable id = session.save(persistentObject);
  if (autoCommit)
  commitTransaction();
  return id;
  } catch (HibernateException ex) {
  log.error("Fail to save persistentObject", ex);
  throw new DaoException("Fail to save persistentObject", ex);
  } finally {
  if (autoCloseSession)
  closeSession();
  }
  }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章