1. ホーム
  2. ハイバーネート

同じ識別子値を持つ別のオブジェクトがすでにセッションに関連付けられている場合。

2022-02-21 06:10:22
 この問題については、オブジェクトをNULLに代入するとうまくいきます。私のシステムでは、更新はうまくいくのですが、挿入がうまくいきません。以前は変化しなかったのですが、挿入はうまくいき、更新はうまくいきません。システムの問題なのですが、catchは引っかかるだけで、ログが出力されないので、原因を探るのが大変でした。HibernateSystemException: a different object with the same identifier value was HibernateSystemException: a different object with the same identifier value was already associated with the session.HibernateSystemException: 同じ識別子値を持つ別のオブジェクトが既にセッションに関連付けられました。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.Net.sf.hibernate SystemException: The same identification value was already associated to the session.4443398: 4443398, of class: com. onewaveinc.media.cms.entity.SyncImportFolder

SyncImportFolder

net.sf.hibernate.NonUniqueObjectException: 同じ識別子値を持つ別のオブジェクトが、すでにセッションに関連付けられていました。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)



org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:421)にて。



com.onewaveinc.media.web.struts.MediaRequestProcessor.processActionPerform(MediaRequestProcessor.java:51)にて、以下のようになります。



org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:226)にて、以下の処理を行います。



at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1164)



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)















同じ識別子値を持つ別のオブジェクトがすでにセッションに関連付けられている場合。



古典的な hibernate エラー: 同じ識別子値を持つ別のオブジェクトが、すでにセッション xxxx に関連付けられていました。



hibernate3.0+ では merge() を使用して、2 つのセッションにある同じオブジェクトをマージすることができます。



具体的には、私自身のコードは



public Object getDomain(Object obj) {...



  getHibernateTemplate().refresh(obj) を実行します。



  objを返します。



  }



  public void deleteDomain(Object obj) { (パブリック ボイド デリート ドメイン)



  obj = getHibernateTemplate().merge(obj);



  getHibernateTemplate().delete(obj) を実行します。



  }











同じ識別子値を持つ別のオブジェクトがすでにセッションエラーに関連付けられていたことを解決する 







このエラーに2回遭遇したのですが、良い解決策が見つかりませんでした。このエラーの原因は、hibernateで同じセッションに同じ識別子が2つあるが異なるエンティティが存在し、saveOrUpdate(object)オペレーションを実行するとこのエラーが報告されることは、誰もが知っていることだと思うのです。ああ、おそらくあなたは言うだろう、あなたは違いがないと言う、私は認める、ああ、私は正確になぜこのエラーがわからない、それ以外の場合は、長い時間が解決されていないでしょう、今、私に一時的な解決を与えるために、同じ、実行を継続する方法の根本原因を見つける方法はありません(もちろん、それは右、ちょうどない開始の原因から)。







実際には、この問題を解決するために非常に簡単ですが、ちょうどsession.clean()操作を行う必要が解決することができますが、クリーン操作で、次にsaveOrUpdate(オブジェクト)操作を行うと、報告されるかもしれません"同じコレクション&quotの二つの表現を発見、私は多くの情報を見つけ、良い説明は、この記事のほとんどは、 [url]http://opensource.atlassian.com/projects/hibernate/browse/HHH-509[/url] 助けがないことです。







最終的には、session.refresh(object) メソッドで解決できます。なお、refreshはhibernateのセッションからオブジェクトを取得するものなので、データベース内に既存のデータを持つオブジェクトでない場合は、session.refresh(object)を使うことができません。セッション内にそのようなオブジェクトがない場合はエラーを報告するので、saveOrUpdate(object)を使用する際にも







もちろん、この問題を解決する最も簡単な方法は、Hibernateに付属しているmerge()メソッドを使用することです。しかし、私はいつも問題が発生したときに、付属のこの非常に便利なメソッド(saveOrUpdate(), save(), update() と比較して)を使うことに非常に違和感を覚えます。







また、このエラーは1対多のマッピングや多対多のマッピングでよく発生することが後でわかりましたので、1対多や多対多のマッピングを使用する場合は注意してください











Hibernateのトラブルシューティング 例外とその処理











1. 同じ識別子値を持つ別のオブジェクトが、すでにセッションに関連付けられていた。







  エラーの理由 hibernate の同じセッション内に、同一だが異なる 2 つのエンティティが存在します。







  解決策1:session.clean()







  追記:clean操作の後にsaveOrUpdate(object)などのデータの状態を変更する操作を行うと、例外 "Found two representations of same collection" が報告される可能性があるそうです。







  解決策2:session.refresh(object)







  追記:オブジェクトがデータベースに既存のデータを持つオブジェクトでない場合、session.refresh(object)は使えません。このメソッドはhibernateセッションからオブジェクトを取得するため、セッションにそのオブジェクトがない場合、エラーを報告します。 object)も使う前に判断する必要があるのですが、どうでしょうか?







  解決策3:session.merge(object)







  追記:Hibernateは内部に独自のメソッドが用意されているので、そちらを使用することをお勧めします。







2. 同じコレクションの2つの表現が見つかった







  エラー理由:1.を参照。







  回避策:session.merge(object)







上記の2つの例外は、1対多のマッピングや多対多のマッピングでよく見られます











同じ識別子値を持つ別のオブジェクトがすでにセッションに関連付けられている場合。



古典的な hibernate エラー: 同じ識別子値を持つ別のオブジェクトが、すでにセッション xxxx に関連付けられていました。



hibernate3.0+ では merge() を使用して、2 つのセッションにある同じオブジェクトをマージすることができます。



具体的には、私自身のコードは



public Object getDomain(Object obj) {...



  getHibernateTemplate().refresh(obj) を実行します。



  objを返します。



  }



  public void deleteDomain(Object obj) { (パブリック ボイド デリート ドメイン)



  obj = getHibernateTemplate().merge(obj);



  getHibernateTemplate().delete(obj) を実行します。



  }



======================================================= 私は仕切り屋です。



実は、私の解決策は、Objを再マージすることです。
public Serializable save(Object persistentObject) throws DaoException {...



  トライ {







  セッション session = this.openSession();



  beginTransaction()を実行します。



persistentObject = session.merge(persistentObject);



  Serializable id = session.save(persistentObject);



  if (autoCommit)



  commitTransaction() を実行します。



  idを返します。



  } catch (HibernateException ex) {.



  log.error("Fail to save persistentObject", ex)を実行します。



  throw new DaoException("Fail to save persistentObject", ex)をスローします。



  } 最終的に {



  if (autoCloseSession)



  closeSession()を実行します。



  }



  }