Удаляет не каскадные для объектов, ссылающихся на себя - PullRequest
0 голосов
/ 09 июня 2010

У меня есть следующие (упрощенные) объекты Hibernate:

@Entity
@Table(name = "package")
public class Package {
    protected Content content;

    @OneToOne(cascade = {javax.persistence.CascadeType.ALL})
    @JoinColumn(name = "content_id")
    @Fetch(value = FetchMode.JOIN)
    public Content getContent() {
        return content;
    }

    public void setContent(Content content) {
        this.content = content;
    }

}


@Entity
@Table(name = "content")
public class Content {
    private Set<Content> subContents = new HashSet<Content>();
    private ArchivalInformationPackage parentPackage;

    @OneToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "subcontents", joinColumns = {@JoinColumn(name = "content_id")}, inverseJoinColumns = {@JoinColumn(name = "elt")})
    @Cascade(value = {org.hibernate.annotations.CascadeType.DELETE, org.hibernate.annotations.CascadeType.REPLICATE})
    @Fetch(value = FetchMode.SUBSELECT)
    public Set<Content> getSubContents() {
        return subContents;
    }

    public void setSubContents(Set<Content> subContents) {
        this.subContents = subContents;
    }

    @ManyToOne(cascade = {CascadeType.ALL})
    @JoinColumn(name = "parent_package_id")
    public Package getParentPackage() {
        return parentPackage;
    }

    public void setParentPackage(Package parentPackage) {
        this.parentPackage = parentPackage;
    }

}

Таким образом, есть один пакет, который имеет один «верхний» контент.Верхний Контент ссылается на Пакет, с каскадом, установленным на ВСЕ.Верхний Контент может иметь много «суб» Контента, а каждый субконтент может иметь множество собственных субконтентов.Каждый субконтент имеет родительский пакет, который может быть или не быть тем же пакетом, что и верхний контент (т. Е. Отношение «многие к одному» для контента к пакету).

Требуются отношениябыть ManyToOne (Пакет к Контенту) и ManyToMany (Контент к Подконтенту), но для случая, в котором я сейчас тестирую, каждый подконтент относится только к одному Пакету или Контенту.когда я удаляю пакет и сбрасываю сеанс, я получаю сообщение об ошибке Hibernate о том, что я нарушаю ограничение внешнего ключа для таблицы subcontents, причем конкретный content_id все еще ссылается на таблицу subcontents.

Я пытался специально (рекурсивно) удалить Содержимое перед удалением Пакета, но получаю ту же ошибку.

Есть ли причина, по которой это дерево сущностей не удаляется должным образом?

РЕДАКТИРОВАТЬ: После прочтения ответов / комментариев я понял, что Контент не может иметь несколько пакетов, а субконтент не может иметь несколько родительских Контентов,поэтому я изменил аннотации с ManyToOne и ManyToMany на OneToOne и OneToMany.К сожалению, это не решило проблему.

Я также добавил двунаправленную ссылку из Контента обратно в родительский Пакет, который я оставил из упрощенного кода.

Ответы [ 2 ]

1 голос
/ 10 июня 2010

Если я правильно понимаю, основываясь на отображении ManyToOne, один Контент имеет много Пакетов, и я предполагаю, что вы удалили поле коллекции «пакетов» из своего класса Контента в своем упрощенном коде выше?

Итак, для вашего поля сбора "пакетов" у вас есть каскадное удаление на нем (точно так же, как то, что у вас есть на вашем субконтенте)? Если вы это сделаете, то я думаю, что это должно работать. Когда вы удаляете корневой контент, он должен выполнять каскадное удаление для каждого субконтента, а затем каждый контент будет выполнять каскадное удаление для пакета.

Это работает?

0 голосов
/ 18 июня 2010

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

...