13

AとBの2つのエンティティがあるとします。Bは次のようにAと多対1の関係にあります。

@Entity
public class A {
  @OneToMany(mappedBy="a_id")
  private List<B> children;
}

@Entity
public class B {
  private String data;
}

ここで、Aオブジェクトを削除し、その削除をすべての子にカスケードしますB。これを行うには2つの方法があります。

  1. cascade=CascadeType.ALL, orphanRemoval=trueOneToManyアノテーションに追加し、データベースからAオブジェクトを削除する前にJPAがすべての子を削除できるようにします。

  2. クラスはそのままにして、データベースに削除をカスケードさせます。

後者のオプションの使用に問題はありますか?エンティティマネージャは、すでに削除されたオブジェクトへの参照を保持しますか?オプション2を選択する理由は、オプション1が削除のためにn + 1個のSQLクエリを生成するためです。これは、オブジェクトAに多数の子が含まれている場合に長時間かかる可能性がありますが、オプション2は単一のSQLクエリのみを生成してから次に進みます。幸せに。これに関する「ベストプラクティス」はありますか?

4

3 に答える 3

9

データベースの方がいいです。なんで?

  • データベースはおそらくこれを行う方がはるかに高速です
  • データベースは、整合性と関係に関する情報を保持するための主要な場所である必要があります。JPAはその情報を反映しているだけです
  • 別のアプリケーション/プラットフォーム (つまり、JPA なし) に接続している場合でも、レコードを段階的に削除できます。これにより、データの整合性が向上します。
于 2011-04-26T09:02:24.540 に答える
7

@CascadeOnDeleteEclipseLinkでは、注釈を使用する場合は両方を使用できます。EclipseLinkは、カスケードDDLも生成します。

http://wiki.eclipse.org/EclipseLink/Examples/JPA/DeleteCascadeを参照して ください。

これにより、データベースに削除を実行させることで削除を最適化するだけでなく、オブジェクトを削除することでキャッシュと永続性ユニットを維持します。

また、コレクションから削除されたオブジェクトも削除されることに注意してくださいorphanRemoval=true。これは、データベースカスケード制約では実行されないため、JPAにルールを設定する必要があります。また、データベースは制約の逆方向にしかカスケードできないOneToOne、外部キーを使用する、またはOneToMany結合テーブルを使用するはデータベースにカスケードできないため、データベースが削除を処理できない関係もあります。

于 2011-04-26T13:26:33.100 に答える
5

この回答は、データベースではなくカスケードを処理するのがJPAであるべき理由について、いくつかの非常に強力な議論を引き起こします。

関連する引用は次のとおりです。

...データベースでカスケードを作成し、(パフォーマンスの問題のために) Hibernate でそれらを宣言しない場合、状況によってはエラーが発生する可能性があります。これは、Hibernate がエンティティをセッション キャッシュに保存するため、データベースがカスケードで何かを削除することを認識しないためです。

第 2 レベルのキャッシュを使用すると、状況はさらに悪化します。このキャッシュはセッションよりも長く存在し、db 側でのそのような変更は、このキャッシュに長い間古い値が格納されているため、他のセッションには見えないためです。

于 2012-08-30T01:44:55.463 に答える