- PR -

Hibernateで更新・削除について

1
投稿者投稿内容
jami
会議室デビュー日: 2003/10/03
投稿数: 11
投稿日時: 2004-11-15 21:18
こんばんわ。jamiです。


ご教授いただきたく、本掲示板に書込みをさせていただきました。
現在、Tomcat + Struts + Hibernate + db2を使用して実装をしています。

Hibernateの処理の中で追加(add)・更新(update)・削除(delete)の処理を行なっているのですが、
変更・削除時のみ下記のExceptionが出力されてしまいます。(※エラー内容参照)

不安要素があるとすれば、DBのカラム名がマルチバイトであること位なのですが、
エラー文言より、色々web上を散策してみたのですが回答は出ていない状況です。

どなたか、ご教授いただけないでしょうか?
何卒、宜しくお願いします。


【処理部分】========================================================================
try {
//セッションチェック
if (session == null) {
throw new Exception("Sessionがありません。");
}

//UPDATE
session.update((NdMemo) obj);

} catch (HibernateException e) {
log.debug("Hibernate例外(HibernateException)が発生しました." , e);
throw e;
} catch (Exception e) {
log.debug("例外(Exception)が発生しました。", e);
throw e;
}
========================================================================


【エラー内容】========================================================================
net.sf.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: 001, of class: jlms.model.vo.NdMemo
at net.sf.hibernate.impl.SessionImpl.checkUniqueness(SessionImpl.java:1677)
at net.sf.hibernate.impl.SessionImpl.doUpdateMutable(SessionImpl.java:1443)
at net.sf.hibernate.impl.SessionImpl.doUpdate(SessionImpl.java:1470)
at net.sf.hibernate.impl.SessionImpl.update(SessionImpl.java:1355)
at jlms.model.nd.list.NdDistPlaceList.updateObject(NdDistPlaceList.java:290)
at jlms.test.model.nd.NdDistPlaceListTest.scenario3(NdDistPlaceListTest.java:120)
at jlms.test.model.nd.NdDistPlaceListTest.testUpdateObject_1(NdDistPlaceListTest.java:256)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:392)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:276)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:167)

【マッピングファイル】========================================================================
<?xml version="1.0" encoding="EUC-JP"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="test.model.vo.NdMemo" table="TBL略称" schema="TEST">
<id name="No" column="番号" type="java.lang.String">
<generator class="assigned"/>
</id>
<property name="Exp" column="説明" type="java.lang.String" length="64"/>
<property name="Name" column="略称" type="java.lang.String" length="16"/>
<property name="insertYmd" column="作成日" type="java.lang.String" length="8"/>
<property name="insertTm" column="作成時間" type="java.lang.String" length="6"/>
<property name="updateYmd" column="更新日" type="java.lang.String" length="8"/>
<property name="updateTm" column="更新時間" type="java.lang.String" length="6"/>
</class>
</hibernate-mapping>




[ メッセージ編集済み 編集者: jami 編集日時 2004-11-15 21:36 ]
komey
ベテラン
会議室デビュー日: 2003/11/27
投稿数: 76
投稿日時: 2004-11-16 12:11
処理前のデータベースの状態、処理内容、処理後に期待するデータベースの状態を書き出してみることをお勧めします。
NonUniqueObjectException=ユニークでないオブジェクトに関する例外なので、
更新/削除したいインスタンスが1つに絞られていないのではないでしょうか。

〜APIリファレンスより〜
This exception is thrown when an operation would break session-scoped identity. This occurs if the user tries to associate two different instances of the same Java class with a particular identifier, in the scope of a single Session.


updateしたいインスタンスobjがデータをあらわすインスタンスNdMemoではないところが少し引っかかります。
普通はNdMemoにデータをsetしていくので、updateのところでキャストすることはないように思うのですが・・・・・・。
コードを省略されただけでしょうか?
でくのぼう
大ベテラン
会議室デビュー日: 2003/10/06
投稿数: 162
投稿日時: 2004-11-16 12:40
obj ってきちんと永続化されてますか?

http://d.hatena.ne.jp/koichik/20040812#1092329105
この辺を参考にしてください。

それから、本筋と関係無いんですけど update って明示的に
呼ぶ必要が無い場合が多いので気をつけましょう。

確か単純に永続化済みのオブジェクトのプロパティを書き換えて
flush() すれば良いはずです。
jami
会議室デビュー日: 2003/10/03
投稿数: 11
投稿日時: 2004-11-16 15:20
ご教授ありがとうございます。

>>komeyさん
>pdateしたいインスタンスobjがデータをあらわすインスタンスNdMemoではないところが少し引っかかります。
>普通はNdMemoにデータをsetしていくので、updateのところでキャストすることはないように思うのですが・・・・・・。
>コードを省略されただけでしょうか?

コードを省略してしまいました。スミマセン。

>>でくのぼうさん
>obj ってきちんと永続化されてますか?
引数として取得したNdMemoオブジェクトをそのままupdateメソッドで渡しているため、
エラーとなっていたようです。

もう一つお聞きしたいのですが、
でくのぼうさんから教えていただいたように、flush()を使用して
下記のよう実装時に、エラーが出てしまいます。

何か知っていたら教えていただけませんでしょうか?
宜しくお願いします。


【コード】=============================================================
NdMemo aNdMemo = (NdMemo)session.load(NdMemo.class, new String(obj.getNo()));
aNdMemo.setDistPgm("テスト");
session.flush();
=======================================================================

【エラー】==================================================================
15:08:42,536 ERROR SessionImpl:2379 - Could not synchronize database state with session
net.sf.hibernate.HibernateException: SQL insert, update or delete failed (row not found)
=======================================================================
1

スキルアップ/キャリアアップ(JOB@IT)