質問

次の方法で注釈が付けられた2つのエンティティクラスがあります

@Entity
class A {
   @ManyToMany(mappedBy="A", cascade=CascadeType.ALL)
   private List<B> b;
 ..
}

@Entity
class B {
   @ManyToMany(cascade=CascadeType.ALL)
   private List<A> a;
 ..
}

クラス「B」のインスタンスを保存すると、リレーションはデータベースに保存され、クラス「A」のゲッターは正しいBのサブセットを返します。ただし、「A」のBのリストに変更を加えた場合、その変更はデータベースに保存されませんか?

質問は、どちらのクラスの変更も「カスケード」されるようにする方法です。他のクラスに?

編集:mappedByパラメーターを削除してJoinTable(および列)を定義するさまざまなバリエーションを試しましたが、正しい組み合わせを見つけることができませんでした。

役に立ちましたか?

解決

最短の答えはあなたにはできないと思われ、それは理にかなっています。双方向の多対多の関連付けでは、一方がマスターである必要があり、基礎となる結合テーブルへの変更を永続化するために使用されます。 JPAはアソシエーションの両側を維持しないため、データベースに格納されるとリロードできないメモリ状況になる可能性があります。 例:

A a1 = new A();
A a2 = new A();
B b = new B();
a1.getB().add(b);
b.getA().add(a2);

この状態を維持できる場合、結合テーブルに次のエントリが作成されます。

a1_id, b_id
a2_id, b_id

しかし、ロードすると、JPAは、a1ではなくa2についてのみbに通知するつもりだったことをどのように知るのでしょうか?そして、bについて知らないa2についてはどうですか?

このため、双方向の関連付けを自分で維持する必要があり(また、上記の例をメモリ内でも取得できないようにします)、JPAはその片側の状態に基づいてのみ持続します。

他のヒント

逆結合列を指定しましたか?

@Entity
class A {
   @ManyToMany(mappedBy="A", cascade=CascadeType.ALL)
   private List <B> b;
   ..
}

@Entity 
class B { 
   @ManyToMany 
   @JoinTable (
       name="A_B",
       joinColumns = {@JoinColumn(name="A_ID")},
       inverseJoinColumns = {@JoinColumn(name="B_ID")}
   )
   private List<A> a; 
   .. 
} 

列A_IDおよびB_IDを持つA_Bという名前の結合テーブルを想定しています。

  

関係が双方向であるため、アプリケーションが更新されます   関係の一方、他方も更新されるはずです、   同期します。 JPAでは、一般的なJavaと同様に、   維持するアプリケーションまたはオブジェクトモデルの責任   アプリケーションが   関係、それから反対側に追加する必要があります。

     

これは、オブジェクトモデルのaddまたはsetメソッドを介して解決できます。   リレーションシップの両側を処理するため、アプリケーションコード   心配する必要はありません。これには2つの方法があります。   関係維持コードを片側にのみ追加できます   関係の片方からのみセッターを使用します(例:   反対側を保護する)、または両側に追加して確認する   無限ループを避けます。

出典: OneToMany#Getters_and_Setters

そのようにクラスBのAフィールドにmappedByパラメーターを追加しようとしましたか

@Entity
class B {
   @ManyToMany(cascade=CascadeType.ALL, mappedBy = "b")
   private List<A> a;
 ..
}

A_Mの答えに小さな間違いがあるかもしれません。 私の意見では:

   @Entity
   class B { 
   @ManyToMany 
   @JoinTable (
       name="A_B",
       joinColumns = {@JoinColumn(name="B_ID")},
       inverseJoinColumns = {@JoinColumn(name="A_ID")}
   )
   private List a; 
   .. 
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top