4

エントリの削除中に制約違反の例外が発生します

私は関係テーブル TransportationEvent と 結論を持っています

関係が似ている

@Entity
public class TransportationEvent {

...

@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
    private List<Conclusion> conclusions = new ArrayList<Conclusion>();

...

}

@Entity
public class Conclusion {

....

@ManyToMany( fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
    private List<TransportationEvent> transportationEvents = new ArrayList<TransportationEvent>();

....

}

ここのデータベースには、次のような別の2つのテーブルがあります

結論_交通イベントと交通イベント_結論

ここで私の要件は、両方のテーブル (TransportationEvent と結論) のレコードを削除する必要があることです。

ここで、次のような結論テーブルのレコードを削除しようとしています:

removeConclusions(conclusion.getId());

 public void removeConclusions(Long id) {
        entityManager = dbConn.getConnection();
        Conclusion conclusion = entityManager.find(Conclusion.class, id);
        entityManager.getTransaction().begin();
        entityManager.remove(conclusion);
        entityManager.getTransaction().commit();
}

しかし、制約違反エラーが発生しています。

原因: java.sql.SQLException: DELETE ステートメントが REFERENCE 制約 "FK30CDAB072AAE439" と競合しました。データベース「ECT」、テーブル「dbo.TransportationEvent_Conclusion」、列「conclusions_id」で競合が発生しました

いくつかのフォーラムを検索して、次のような構文を得ました

@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)

そして私はそれを次のように適用しました

@ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
    @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
    private List<Conclusion> conclusions = new ArrayList<Conclusion>();

@ManyToMany( fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
    private List<TransportationEvent> transportationEvents = new ArrayList<TransportationEvent>();

同じ制約違反が発生しているにもかかわらず、両方のエンティティで

結論と交通イベントからレコードを削除するためにこれをどのように使用する必要があるかを教えてください。

前もって感謝します!

4

1 に答える 1

6

問題を特定しましたが、修正しませんでした。TransportationEvent と結論の間の関連付けを保持するために、2 つの異なる結合テーブルを持つべきではありません。1つ持っている必要があります。

単一の双方向の ManyToMany アソシエーションは定義していませんが、2 つの別個の一方向の ManyToMany アソシエーションを定義しています。双方向アソシエーションでは、一方の側は常に、所有者側である他方の側の逆側でなければなりません。逆側にはmappedBy属性が必要です。したがって、TransportationEvent を所有者側として選択した場合、マッピングは次のようになります。

@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
private List<Conclusion> conclusions = new ArrayList<Conclusion>();

@ManyToMany(mappedBy = "conclusions" fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
private List<TransportationEvent> transportationEvents = new ArrayList<TransportationEvent>();

そして今、関連付けを消滅させるには、イベントの結論のリストから結論を削除するだけです。一貫性のあるオブジェクト グラフを作成するには、結論のイベント リストからイベントを削除することもお勧めしますが、Hibernate は逆側を気にしません。所有者側のみ。

結論がイベントから削除されると、それは参照されなくなり、データベースから削除できます。

于 2013-05-22T13:19:02.633 に答える