2017-05-03 28 views
1

私は同様の質問をたくさん見ていますが、それを結びつける決定的なものは見つかりませんでした。JPAでのカスケード削除@OneToManyとデータベースカスケードの外部キーの削除

JPAを使用する場合、@OneToMany関係がある場合は、REMOVE操作をカスケードするように指定できます。同時に、キーベース行が削除された場合に実行するアクションでデータベースに外部キーを指定することができます。

JPA例:データベースで

@Entity 
public class Parent { 

    @Id 
    private Long id; 
    @OneToMany(cascade = {CascadeType.REMOVE}) 
    private List<Child> children; 
    // getters, setters... 

} 

@Entity 
public class Child { 

    @Id 
    private Long id; 
    @ManyToOne(optional = false) 
    @JoinColumn(name = parent_id, nullable = false) 
    private Parent parent; 
    // getters, setters... 

} 

Childテーブルは、次にParentid列に対する外部キー制約とカラムparent_idを有するであろう。

削除時にカスケードするための外部キー制約で可能なアクションは、delete,set to nullおよびdo nothingです。これにより、以下のシナリオの組み合わせが得られます。

 
     JPA | cascade | no cascade | 
      | remove | remove  | 
DB FK  |   |   | 
-----------+---------+------------| 
delete  | A |  D  | 
-----------+---------+------------| 
set null | B |  E  | 
-----------+---------+------------| 
do nothing | C |  F  | 
-----------+---------+------------+ 
  • A:カスケードは、JPAで親に電話を削除し、彼らはへの外部キーを持つ親行の削除時にデータベースに子供を削除します。
  • B:JPAでカスケード削除を行い、親削除のデータベースで子テーブルの外部キー列をnullに設定します。 @JoinColumnのnullableおよび/またはの@ManyToOneは、おそらくこの場合はtrue/falseである必要があります。
  • C:JPAでカスケード削除します。データベースで外部キーを削除しても何も実行しません。
  • D:JPAでカスケード削除を実行せず、データベース内の親のカスケード削除を実行しないでください。
  • E:JPAで削除をカスケードしないでください。親deleteのデータベースでChildテーブルの外部キー列をnullに設定してください。
  • F:JPAで削除をカスケードしないでください。外部キーを削除しても、データベースは何も実行しないでください。

です。

これらのシナリオのどれが例外につながりますか?図Cの場合。 ParentインスタンスをEntityManager経由で削除すると、そのインスタンスでコールが行われた後、コレクションプロパティのChildインスタンスにカスケードされます。しかし、関連する子を最初に削除せずにデータベースから親を削除しようとすると、外部キー違反が発生します。これは正しいです?他の不具合のシナリオはありますか? Woud原因は、基盤となるDBからすでに削除されている永続性からエンティティを削除しようとすると問題が発生しますか?

これは、EntityManagerキャッシュをデータベースと一貫性のない状態にしますか?私はそれがDとEだと思っています。このような場合は、子リストのインスタンスに対してremove()を自分で呼び出す必要があります。

JPAレイヤーとデータベースの両方でデータの整合性を強化するために使用する設定はどれですか? Aはトリックを行いますか?データベース自体が親を削除する際に外部キー列をnullに設定し、JPAが子インスタンスを削除できるため、Bも機能すると思います。

答えて

0
  • 例外シナリオ:

私がBだと思うし、外部キーフィールドがNULL可能でないため、Eは、あまりにも例外につながります。

nullで値を更新すると、例外が発生します。

  • JPAとデータベース間の一貫性を実現

私はA、またはFを使用すると、それを達成すると思います。どちらの場合も、両方のレイヤーで同じアクションが実行されます。

関連する問題