У меня есть родительский объект, которому принадлежит (через mappedBy) набор FetchType.LAZY с orphanDelete = true.
Клиент может успешно добавлять и удалять дочерние строки через получатель родительской коллекции, и их изменения правильно фиксируются после em.merge (parent).
Однако, если клиент объединяет родителя БЕЗ доступа к дочерней коллекции, все дочерние строки удаляются при фиксации родителя.
Такое же поведение демонстрируется в OpenJPA 2.1.0 и двоичном снимке 2.1.1-20110610.205956-18.
Любые указатели приветствуются.
Пример для иллюстрации:
@Entity
public class Parent{
@Column
private String name;
@OneToMany(mappedBy="parent", fetch=LAZY, cascade = ALL, orphanRemoval=true)
private Set<Child> children;
public String getName(){return name;}
public void setName(String name){this.name=name;}
public Set<Child> getChildren(){
return children;
}
}
@Entity
public class Child{
@ManyToOne(optional = false, targetEntity = Parent.class)
@JoinColumn(name="parent_id", nullable=false)
private Parent parent;
}
Обе сущности имеют объявленные свойства @Id и @Version и реализуют соответствующие методы hashCode, equals и compareTo.
Следующий код клиента работает отлично, имя parent.name обновлено, 1 дочерний элемент вставлен, а 1 дочерний элемент удален
EntityTransaction eTx=em.getTransaction();
eTx.begin();
Parent par=em.find(Parent.class, parId);
//PersistenceUnitUtil.isLoaded(par) returns true
//PersistenceUnitUtil.isLoaded(par, "children") returns false
Collection<Child> children=par.getChildren();
//PersistenceUnitUtil.isLoaded(par, "children") returns true
Child child = children.iterator().next();
par.getChildren().remove(child);
par.getChildren().add(new Child(par, "I'm New"));
par.setName("I am Updated");
par=em.merge(par);
eTx.commit();
Следующий код выдаст команды удаления для каждого из потомков родителя:
EntityTransaction eTx=em.getTransaction();
eTx.begin();
Parent par=em.find(Parent.class, parId);
//PersistenceUnitUtil.isLoaded(par) here returns true, and
//PersistenceUnitUtil.isLoaded(par, "children") returns false
par.setName("I am Updated");
par=em.merge(par);
eTx.commit();