Мой вопрос здесь почти аналогичен моему другому вопросу Явное удаление по отношениям 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;
}
В моем пользовательском интерфейсе я показываю список родителей. Пользователь может выбрать одного родителя, и он может редактировать список своих детей. Чтобы показать это, я использовал переменную 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);
}
}
}
Моя проблема в том, что я могу изменить имя родителя, но любые изменения в списке дочерних элементов не отражаются в БД. Он не изменяет и не выполняет какой-либо SQL для удаления/обновления/добавления дочерних элементов.
В чем может быть причина?
UPDATE
Хорошо после некоторых проб и ошибок и чтения через различные ссылки, кажется, что установка опции orphanRemoval в моем @onetomany решит мою проблему. Eclipselink автоматически удаляет строки сирот во время слияния.
Так много для сложности JPA.
@Entity
public class Parent {
private String name;
@OneToMany(mappedBy="owner",cascade=CascadeType.ALL, fetch=FetchType.EAGER,orphanRemoval = true)
private List<Child> children;
}