0

クラスBとOneToManyの関係を持つクラスAがある状況があります。クラスBは、id、firstName、lastNameなどのいくつかの属性のみで構成されています。IDはUUIDを介して生成されます。Aのインスタンスの多くがfirstNameとlastNameに同じ値を持つBのインスタンスを参照する可能性が非常に高いため、Bのインスタンスのこれらの値が変更される可能性はほとんどありません。そこで、重複を避け、他のパラメーターが同じである場合は、AのインスタンスをBの同じインスタンス(データベース内)に参照させることにしました。

例:

b: "John Doe"
a: a1 ("Foo Bar", "John Doe"), a2 ("John Doe", "Alan Smith").

これを実現するために、新しいBがAに追加された場合は、常に同じパラメーターを持つ既存のレコードをデータベースでチェックします。その場合は、BのそのインスタンスのIDをデータベースのIDで上書きして追加します。その後Aに。

ここに私の問題があります。すべて正常に動作していますが、データベースにすでに存在するBと同じIDになるようにBのIDを手動で変更したAを永続化すると、例外が発生します。

Caused by: org.hibernate.exception.ConstraintViolationException:
Duplicate entry '2cfa1412-5f64-4a9c-b55c-f7db1148bef9' for key 'PRIMARY'

だから私の質問は:

  • 例外を無視せずにこの問題を修正するにはどうすればよいですか?
  • これは私のニーズに合う良い方法ですか?

よろしくお願いします

4

1 に答える 1

1

まず第一に、OneToMany ではなく、ManyToMany があります。

ここで、問題を解決するには、接続された B の ID を detachedB に割り当てず、接続された B を接続された B に置き換えます。

Set<B> bs = new HashSet<B>(a.getBs()); // copy the list of Bs
a.getBs().clear();
for (B b : bs) {
    B existingB = searchBWithSameValuesAs(b);
    if (existingB != null) {
        a.getBs().add(existingB);
    }
    else {
        em.persist(b);
        a.getBs().add(b);
    }
}
于 2012-05-06T06:37:39.947 に答える