Коллекция с каскадом = "all-delete-orphan" больше не ссылалась на экземпляр объекта-владельца
В моем приложении операция спящего режима выполняется следующим образом.
Приложение обновляет родительский объект с новыми значениями из запроса и удаляет все существующие (ранее вставленные) дочерние сущности и вставляет новые дочерние записи.
Я использую hibernates DELETE_ORPHAN
для этого, как вы можете видеть ниже.
Когда я делаю это, я получаю следующее исключение:
org.hibernate.HibernateException: коллекция с cascade = "all-delete-orphan" больше не ссылался на владельца экземпляр объекта: com.childs
Я видел похожие темы с проблемой, и я попытался добавить решения в эти потоки. Но это не сработало
Мой родительский объект
public class Parent implements Serializable {
@Column(name = "PARENT_ID")
@Basic(fetch = FetchType.EAGER)
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq")
@SequenceGenerator(name = "seq", sequenceName = "seq")
private Integer parentId; //primary key of parent
.......
........
//mapping to child entity
@OneToMany(mappedBy = "parent", cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
private Set<Child> childs;
................
...............
}
Детский объект имеет комбинированный ключ и имеет объект PK, показанный ниже
public class ChildPK implements Serializable {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = -447592368963477750L;
/** . */
@ManyToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
@JoinColumns( { @JoinColumn(name = "PARENT_ID", referencedColumnName = "PARENT_ID") })
@Id
private Parent parent;
/**. */
@Column(name = "CHILD_ID")
@Basic(fetch = FetchType.EAGER)
@Id
@GenericGenerator(name="child_seq", strategy="com.DB2Dialect")
@GeneratedValue(generator="child_seq")
private Integer childId;
}
child entity goes like this:
public class Child implements Serializable {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 185670997643552301L;
/** The pol cntct id. */
@Column(name = "CHILD_ID")
@Basic(fetch = FetchType.EAGER)
@Id
private Integer childId;
@ManyToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
@JoinColumns( { @JoinColumn(name = "PARENT_ID", referencedColumnName = "PARENT_ID") })
@Id
private Parent parent;
}
Код Java
...................
..............
parent.getChild().clear();
Child child = new Child();
parent.setChild(child);
Что может быть неправильно здесь.
Спасибо заранее...
Ответы
Ответ 1
Ваш последний фрагмент кода Java не компилируется. Думаю, это выглядит как
parent.getChilds().clear(); // note: you should name it children rather than childs
parent.setChilds(someNewSetOfChildren):
Не выполняйте последнюю инструкцию. Вместо замены набора другим, очистите набор и добавьте новых детей в очищенный набор:
parent.clearChildren();
parent.addChildren(someNewSetOfChildren);
где методы определены как:
public void clearChildren() {
this.children.clear();
}
public void addChildren(Collection<Child> children) {
this.children.addAll(children);
}
Метод setChildren следует полностью удалить или заменить на следующую реализацию:
public void setChildren(Collection<Child> children) {
this.children.clear();
this.children.addAll(children);
}
Ответ 2
Это сработало для меня.
- Очистили все дочерние объекты.
-
Вместо того, чтобы устанавливать новые дочерние объекты в родительский объект, я использовал метод addAll для добавления новых дочерних объектов.
parent.getChildren().clear();
parent.getChildren().addAll(newChildrenList);
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY,
cascade = CascadeType.ALL, orphanRemoval = true)
public Set<Children> getChildren() {
return this.children;
}
Ответ 3
Я столкнулся с той же проблемой и решил ее решить следующим образом:
1- добавить {CascadeType.ALL}, orphanRemoval = true во всех @OneToMany аннотациях во всей сущности Childs этого элемента.
2- Проверьте hashcode() и equalls() этих объектов, иногда у них есть erros
3- Не используйте parent.setChilds(newChilds);
, так как двигатель попросит пропустить ссылку на дочерние элементы, но вместо этого используйте
parent.getChilds().clear();
parent.getChilds().add(Child);
или
parent.getChilds().addAll(Childs);
Эти шаги решили мою проблему после 4 часов исследований
Ответ 4
вместо setChilds
используйте addAll
,
parent.getChilds().clear();
parent.setChilds(newChilds);
к
parent.getChilds().clear();
parent.getChilds().addAll(newChilds);