ここでの私の質問は、他の質問JPA 関係の明示的な削除とほとんど似ていますが 、より詳細な回答を保証するために、さらに単純化することを考えました。
親と子の間に OneToMany 関係があるとします。
@Entity
public class Parent {
private String name;
@OneToMany(mappedBy="owner",cascade=CascadeType.ALL, fetch=FetchType.EAGER)
private List<Child> children;
}
@Entity
public class Child {
private String name;
@ManyToOne
private Parent owner;
}
私の UI では、親のリストを表示しています。ユーザーは 1 つの親を選択でき、その子のリストを編集できます。これを示すために、 currentParent 変数を使用して、現在編集されている親を表しています。ユーザーは、子供の名前を追加/編集することを選択できます。
ボタンをクリックすると、EJB 呼び出しを使用して新しい子のリストを保存します。
@ViewScoped
public class MyBean(){
private Parent currentParent;
@EJB
private MyEJB myEJB;
public void saveChanges(){
myEJB.save(currentParent);
}
}
私の EJB 呼び出しは次のようになります。
@Stateless
public class MyEJB{
@PersistenceContext(unitName = "MyPU")
private EntityManager em;
public void save(Parent parentNew){
Parent pOld = em.find(entityClass, p.getId());
if(pOld !=null){
pOld.setName(parentNew.getName());
pOld.setChildren(parentNew.getChildren());
em.merge(pOld);
}
}
}
私の問題は、親の名前を変更することはできますが、子リストへの変更は DB に反映されないことです。子を削除/更新/追加するために SQL を変更または実行することはありません。
原因は何ですか?
アップデート
いくつかの試行錯誤とさまざまなリンクを読んだ後、 @onetomany で orphanRemoval オプションを設定すると問題が解決するようです。Eclipselink は、マージ中に孤立した行を自動的に削除します。
JPAの複雑さはこれで終わりです..
@Entity
public class Parent {
private String name;
@OneToMany(mappedBy="owner",cascade=CascadeType.ALL, fetch=FetchType.EAGER,orphanRemoval = true)
private List<Child> children;
}