繁体   English   中英

删除不级联的自引用实体

[英]Deletes not cascading for self-referencing entities

我有以下(简化的)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;
    }

}

因此,只有一个包,其中包含一个“顶部”内容。 顶部的内容链接返回到包,级联设置为ALL。 顶部内容可能具有许多“子”内容,并且每个子内容可能具有其自己的许多子内容。 每个子内容都有一个父包,该父包与顶部内容可能相同,也可能不相同(即,内容与包之间是多对一关系)。

这些关系必须是ManyToOne(内容打包)和ManyToMany(内容到子内容),但是对于我目前正在测试的情况,每个子内容仅与一个包或内容有关。

问题是,当我删除Package并刷新会话时,会收到一个Hibernate错误,指出我违反了对表subcontents的外键约束,并且仍然从表subcontents引用了特定的content_id

我曾尝试(递归地)先删除目录,然后再删除软件包,但遇到相同的错误。

为什么没有正确删除该实体树的原因?

编辑:阅读答案/评论后,我意识到一个内容不能具有多个包,而一个子内容不能具有多个父内容,因此我将批注从ManyToOne和ManyToMany修改为OneToOne和OneToMany。 不幸的是,这不能解决问题。

我还添加了从Content返回到父Package的双向链接,而忽略了简化代码。

如果我正确理解的话,基于ManyToOne映射,一个内容具有许多包,并且我假设您在上面的简化代码中从Content类中删除了“包”集合字段?

那么,对于您的“ packages”集合字段,您是否具有级联删除功能(就像子内容中的内容一样)? 如果您这样做,那么我认为它应该起作用。 当您删除根目录内容时,它应该对每个子内容执行级联删除,然后每个内容将对程序包执行级联删除。

那样有用吗?

事实证明,该问题是由于删除每个Package之后我正在刷新并清除会话而造成的,并且由于模型中的循环依赖关系,并未删除所有内容。 需要刷新和清除,因为涉及非常大的数据集。 最后,我对其进行了更改,以便构造一组依赖于当前Package的所有实体(其中可能包括其他Package),然后在调用flush和clear之前将其全部删除。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM