3

次のように、クラス A からクラス B への一方向の 1 対多の関連付けがあるとします。

public class A {
    @OneToMany(cascade = CascadeType.ALL)
    private List<B> myBs;
}

public class B {
    //I know nothing about A
}

データベースでは、これらは 3 番目のテーブルを介して接続され、ID を保持します。

ここで、A に接続されている B オブジェクトを削除したいと思います。A には独自のリポジトリ クラスがあり、B には独自のリポジトリ クラスがあります。

これが私のプロジェクトの同様の設定で行われた方法は、最初に問題の A に問題の B を削除するように依頼し、次にEnitityManagerデータベースから B を削除するように指示することです。

これにより、2 つの選択肢の間で少し行き詰まります。どちらも私の考えでは最適ではありません。

  1. のリポジトリ メソッドはBRepository、接続先の A からの B の削除と、 を介したデータベースからの削除の両方を処理しますEntityManager。B のリポジトリ クラスが A オブジェクトを操作しなければならないので、私はこれが好きではありません。

  2. BRepository のリポジトリ メソッドは、EntityManager による削除のみを処理し、A のコレクションからの削除は呼び出し元に任せます。A のコレクションから B を最初に削除せずに誰かがリポジトリを呼び出すと、ひどく失敗するため、これはさらに好きではありません。

2つのうち、最初のものが断然最高だと思います。しかし、それでも、私はそれがきれいだとは本当に思いません。

Hibernate には、データベースからの削除時に、アイテムが含まれているコレクションからアイテムを削除できるようにする構造がありますか? (B を含む A も同じトランザクションにロードされているため、B を削除しようとすると失敗します。そのため、削除されたものを保存しようとすると、トランザクションの終了時に失敗します。)

( in A を追加mappedByする@OneToMany-mappingと問題は解決しますか?)

4

3 に答える 3

3

孤立した削除を使用して、これを解決する方法を見つけました。

A のマッピングを次のように変更します。

public class A {
   @OneToMany(cascade = CascadeType.ALL)
   @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
   private List<B> myBs;
}

私はただ言うことができます

a.getMyBs().remove(b);

永続化bされると削除されます。a

于 2012-09-11T14:34:39.110 に答える
2

Hibernate の考え方から抜け出し、次のことを自問してくださいB

所有者は、自分の財産に対して最終的な責任を負います。B通常、これは、なしでが存在できずA、それぞれBが正確に 1 つの によって所有されている場合に当てはまりますA

したがって、が をA所有している場合BARepositoryは をクリーンBアップする責任があります。ARepositoryでクリーンアップを行い、で削除メソッドを呼び出すメソッドを作成しBRepositoryます。

于 2012-09-11T13:34:55.583 に答える
0

リポジトリを本当に分離したい場合は、他のオプションは、両方を認識し、オプション 1 のアプローチと同様の方法で削除を処理するサービス クラスを上部に作成することです。

(Aの@OneToMany-mappingにmappedByを追加すると問題は解決しますか?)

これは、リポジトリの実装に依存すると思います。JPA EntityManager の場合、セッションが閉じている場合、双方向マッピングであっても B を削除すると A がデタッチされます。

于 2012-09-11T13:41:53.427 に答える