3

私のクラスFooにはメソッドがあります:

 protected void saveMany(Collection<T> many) {  
    for(Object one : many) {
            one = session.merge(one); // also tried this commented out
            session.saveOrUpdate(one); // session.merge(one);   
        }

saveOrUpdate とマージを使用しようとしましたが、どちらも次の例外を与えました:

Error: Invocation of method 'saveMany' in class Foo threw exception class org.hibernate.HibernateException : org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [Bar#581301]

これを修正する方法は?

サイドノート:

テーブルを切り捨てると、保存部分は機能しますが、テーブルにデータを入力してこのメ​​ソッドを再度実行すると、テーブルが更新され、この例外が発生して失敗します

4

4 に答える 4

6

@IdHibernateセッションキャッシュにすでに存在するクラスのデタッチされたインスタンスがある場合は、デタッチされmerge()たインスタンスをキャッシュにマージするために呼び出す必要があります。次に、を呼び出す必要がありますsaveOrUpdate()

ただし、パラメータとして渡したインスタンスではなく、merge()の呼び出しから返されたインスタンスを永続化するように注意する必要があります。したがって、コードは次のようになります。

mergedOne = session.merge(one);
session.saveOrUpdate(mergedOne);

トランザクション内で操作している場合、セッションが終了してトランザクションがコミットされるか、明示的に呼び出すまで、データベースは更新されません。flush()

于 2012-08-13T14:51:02.967 に答える
1

別のオブジェクトですでに使用されているIDを使用して新しいオブジェクトを保存しようとしていることを示しています。

equalsおそらく、適切に実装されていませんhashCode。したがって、hibernateは、Object2をid1で保存することを検出し、データベースにはObject2をid1で保存しますが、Object2.equals(Object1)

于 2012-08-13T13:18:19.127 に答える
0

Hibernatesessionsのキャッシュに「one」の複数のバージョンがあります。

「one」のインスタンスを見つけ、「。evict(...)」を使用してHibernatesessionsからキャッシュ情報を削除する必要があります。

最後に、saveOrUpdateを正常に呼び出すことができます。

于 2012-08-13T13:20:03.110 に答える
0

List<T>1 つ以上の equals オブジェクトを含む保存を試みている可能性があります。

SaveOrUpdate または merge を使用して解決するか、単にすべてのオブジェクトを一意にしようとします。

于 2012-08-13T13:21:44.207 に答える