0

我有以下(简化的)休眠实体:

@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。顶部内容可能有许多“子”内容,每个子内容可能有许多自己的子内容。每个子内容都有一个父包,它可能是也可能不是与顶级内容相同的包(即内容与包的多对一关系)。

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

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

我已经尝试在删除包之前专门(递归地)删除内容,但我得到了同样的错误。

这个实体树没有被正确删除是有原因的吗?

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

我还添加了从内容返回到父包的双向链接,这是我在简化代码中遗漏的。

4

2 回答 2

1

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

那么,对于您的“包”集合字段,您是否对其进行了级联删除(就像您对子内容的内容一样)?如果你这样做,那么我认为它应该工作。当你删除根内容时,它应该对每个子内容进行级联删除,然后每个内容都会对包进行级联删除。

那样有用吗?

于 2010-06-09T20:03:25.780 回答
0

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

于 2010-06-18T00:15:38.823 回答