こんにちは、みんな、
私は現在、コーディングとエンティティ モデルの何が問題なのかを理解しようとしています。一般的な DAO パターンと、カスケード ALL および orphanRemoval= true の注釈付きエンティティのみを使用した CRUD 操作に、hibernate 4.2 を使用しています。DayPlanElement弱いエンティティとのOneToMany 関係を持つ DayPlan エンティティがあります。DayPlanElement は java.util.Set に保存されます。各DayPlanElementにはプロパティ「order」があります。
DayPlanには、エンティティPersonとのOneToMany 関係もあります。java.util に保存されたエンティティPerson 。リスト。
DayPlanElementは、DayPlanElementEntryウィーク エンティティと OneToMany の関係にあります。保存に使用される java.util.Set。Personエンティティも、 DayPlanElementEntryウィーク エンティティとのOneToMany 関係です。保存に使用される java.util.Set。DayPlan 、DayPlanElement 、および Personエンティティには、アプリケーションによって管理される ID が文字列として含まれています。DayPlanElementEntryウィーク エンティティには、EmbeddedId で注釈が付けられたDayPlanElementEntryId という複合 ID があり、parentPersonId と dayPlanElementId が含まれています。これ
つまり想像してみると、テーブルが存在し、その日の予定を表しています。列は 0 から 24 までの時間です。行は、1 日の計画から作業を進める必要がある人です。各列は DayPlanElement エンティティになります。各行は Person エンティティになります。そして、各セルは DayPlanElementEntry エンティティになります。
テーブルに新しい要素(Personsも)を追加して削除するだけで(リストから削除してから、DayPlanDAO.merge(dayPlan)を呼び出します-カスケードとorphanRemovalを希望します)-問題はありません。
指定された人物を並べ替えようとした場合 (java.util.List 内の操作を削除するだけ)、DayPlanDAO.merge(dayPlan) を呼び出した場合にのみ、次の例外がスローされます。
Caused by: java.lang.IllegalStateException:
Error occurred while storing entity
[DayPlanElementEntry [getDayPlanMode()=NONE, getCompositeId()=DayPlanElementEntryId [parentPersonId=874c8eac-8796-478d-a4d5-dd011f7d6a4b, dayPlanElementId=ab683a25-633e-419e-89b6-4aef7829d4f6], hashCode=-2039940039]].
An entity copy
[org.hw.domain.DayPlanElementEntry#DayPlanElementEntryId [parentPersonId=874c8eac-8796-478d-a4d5-dd011f7d6a4b, dayPlanElementId=ab683a25-633e-419e-89b6-4aef7829d4f6]]
was already assigned to a different entity
[org.hw.domain.DayPlanElementEntry#DayPlanElementEntryId [parentPersonId=874c8eac-8796-478d-a4d5-dd011f7d6a4b, dayPlanElementId=ab683a25-633e-419e-89b6-4aef7829d4f6]].
at org.hibernate.event.internal.EventCache.put(EventCache.java:192)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:285)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:151)
EventCache をデバッグし、問題の解決策を探し、実装された equals() および hashCode() メソッドをチェックするだけです - 成功しませんでした:-(( 注意、equals() メソッドには ID を使用します。たとえば、DayPlanElementEntry の複合 ID。その ID hashCode() で使用されます。エラー メッセージがわかりません。同じプロパティが 3 回出力されます。
イベント キャッシュのテスト クラスは見つかりましたが、次のユース ケース テストがわかりません。
@Test
public void testCopyAssociatedWith2ExistingEntities() {
session.getTransaction().begin();
Simple entity1 = new Simple( 1 );
session.persist( entity1 );
Simple copy1 = new Simple( 1 );
cache.put(entity1, copy1);
Simple entity2 = new Simple( 2 );
session.persist( entity2 );
Simple copy2 = new Simple( 2 );
cache.put( entity2, copy2 );
session.flush();
try {
cache.put( entity1, copy2 );
fail( "should have thrown IllegalStateException");
}
catch( IllegalStateException ex ) {
// expected
assertTrue( ex.getMessage().startsWith( "Error occurred while storing entity [org.hibernate.event.internal.EventCacheTest$Simple#1]." ) );
}
session.getTransaction().rollback();
}
....
@Entity
private static class Simple {
@Id
private int value;
public Simple(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
Id=1の Simple エンティティ entity1 があり、それを永続化します。次に、Simple エンティティ copy1 を作成し、それを値としてイベント キャッシュに入れます。キーとして永続エンティティ* 1 * が使用されます。次に、 Id=2でSimple entity* 2 *を作成し、それを永続化してから、id 2 で copy* 2 * エンティティを作成し、値としてイベント キャッシュに入れます。キーとして、永続化されたentity2が使用されました。なぜそのような状況が間違っていて、なぜ IllegalStateException をスローする必要があると予想されるのですか??
ご協力いただきありがとうございます!