次のシナリオを考えます。
@Entity
public class A {
@OneToMany(mappedBy = "a", cascade = CascadeType.ALL)
private List<B> bList;
}
@Entity
public class B {
@ManyToOne()
@JoinColumn(name = "a_id", referencedColumnName = "id")
private A a;
@ManyToOne()
@JoinColumn(name = "c_id", referencedColumnName = "id")
private C c;
}
@Entity
public class C {
@OneToMany(mappedBy="c", cascade=CascadeType.ALL, orphanRemoval=true)
@CascadeOnDelete // eclipselink specific optimization annotation
private List<B> bList;
}
つまり、オブジェクトAとオブジェクトCの両方に多数のBオブジェクトが含まれています。
Cオブジェクトを削除するとき(技術的には、複数のCオブジェクトを含むオブジェクトを更新し、orphanremovalを使用しています)、現在のアノテーションで期待どおりに機能する、参照されているすべてのBオブジェクトを削除したいと思います。ただし、エンティティマネージャは、キャッシュ内にあるオブジェクトAが一部の子を失ったことを理解していないようです。Aのインスタンスがある場合は、もちろんそのbListを手動で更新するか、新しいクエリを実行して更新する必要がありますが、新しくフェッチされたAオブジェクトでさえまだ古くなっています。繰り返しますが:
- Cオブジェクトが削除されます。
- 削除は、orphanRemovalを使用してBオブジェクトにカスケードされます。
- エンティティマネージャにキャッシュされているオブジェクトのbListは更新されません。
- エンティティマネージャのキャッシュを手動で削除すると、適切に更新されたオブジェクトが取得されます。
これはどのように解決できますか?エンティティマネージャーが永続コンテキストを自動的に更新するか、@ JoinColumnでカスケードアノテーションを利用できるようにすることを期待しますが、ここではどちらも当てはまらないようです。
編集:問題は、オブジェクトAのbListが更新されたときにオブジェクトCのbListが更新されないことにあるようです(したがって、変更をカスケードできません)。理由はわかりませんが、インスタンス化されたオブジェクトではなく、永続コンテキストについて話していることに注意してください。