На коллекцию с cascade = "all-delete-orphan" больше не ссылался экземпляр-владелец - PullRequest
15 голосов
/ 24 февраля 2012

В моем приложении операция гибернации выглядит следующим образом.Приложение обновляет родительскую сущность новыми значениями из запроса и удаляет все существующие (ранее вставленные) дочерние сущности и вставляет новые дочерние записи.

Для этого я использую спящие 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);

Что тут может быть не так.
Заранее спасибо ...

Ответы [ 4 ]

52 голосов
/ 24 февраля 2012

Ваш последний фрагмент кода 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);
}
9 голосов
/ 10 апреля 2014

у меня сработало.

  1. Очистил все мои дочерние сущности.
  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;
    }
    
7 голосов
/ 23 ноября 2016

Я столкнулся с той же проблемой и решил ее следующим образом:

1 - добавить {CascadeType.ALL}, orphanRemoval = true во всех @ OneToMany аннотациях во всех дочерних объектах этого элемента.

2- Проверьте хеш-код () и равно () этих объектов, иногда они имеют ошибки

3 - Не используйте parent.setChilds(newChilds);, так как движок попросит пропустить ссылку на childs, но вместо этого используйте

parent.getChilds().clear();
parent.getChilds().add(Child);

или

parent.getChilds().addAll(Childs);

Эти шаги решили мою проблему после 4 часов исследования

4 голосов
/ 16 октября 2014

вместо setChilds используйте addAll,

от этого,

    parent.getChilds().clear();
    parent.setChilds(newChilds);

до

    parent.getChilds().clear();
    parent.getChilds().addAll(newChilds);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...