简体   繁体   English

删除不级联的自引用实体

[英]Deletes not cascading for self-referencing entities

I have the following (simplified) Hibernate 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;
    }

}

So there is one Package, which has one "top" Content. 因此,只有一个包,其中包含一个“顶部”内容。 The top Content links back to the Package, with cascade set to ALL. 顶部的内容链接返回到包,级联设置为ALL。 The top Content may have many "sub" Contents, and each sub-Content may have many sub-Contents of its own. 顶部内容可能具有许多“子”内容,并且每个子内容可能具有其自己的许多子内容。 Each sub-Content has a parent Package, which may or may not be the same Package as the top Content (ie a many-to-one relationship for Content to Package). 每个子内容都有一个父包,该父包与顶部内容可能相同,也可能不相同(即,内容与包之间是多对一关系)。

The relationships are required to be ManyToOne (Package to Content) and ManyToMany (Content to sub-Contents) but for the case I am currently testing each sub-Content only relates to one Package or Content. 这些关系必须是ManyToOne(内容打包)和ManyToMany(内容到子内容),但是对于我目前正在测试的情况,每个子内容仅与一个包或内容有关。

The problem is that when I delete a Package and flush the session, I get a Hibernate error stating that I'm violating a foreign key constraint on table subcontents , with a particular content_id still referenced from table subcontents . 问题是,当我删除Package并刷新会话时,会收到一个Hibernate错误,指出我违反了对表subcontents的外键约束,并且仍然从表subcontents引用了特定的content_id

I've tried specifically (recursively) deleting the Contents before deleting the Package but I get the same error. 我曾尝试(递归地)先删除目录,然后再删除软件包,但遇到相同的错误。

Is there a reason why this entity tree is not being deleted properly? 为什么没有正确删除该实体树的原因?

EDIT: After reading answers/comments I realised that a Content cannot have multiple Packages, and a sub-Content cannot have multiple parent-Contents, so I have modified the annotations from ManyToOne and ManyToMany to OneToOne and OneToMany. 编辑:阅读答案/评论后,我意识到一个内容不能具有多个包,而一个子内容不能具有多个父内容,因此我将批注从ManyToOne和ManyToMany修改为OneToOne和OneToMany。 Unfortunately that did not fix the problem. 不幸的是,这不能解决问题。

I have also added the bi-directional link from Content back to the parent Package which I left out of the simplified code. 我还添加了从Content返回到父Package的双向链接,而忽略了简化代码。

If I understand correctly, based on the ManyToOne mapping, one Content has many Packages, and I assume you removed the "packages" collection field from your Content class in your simplified code above? 如果我正确理解的话,基于ManyToOne映射,一个内容具有许多包,并且我假设您在上面的简化代码中从Content类中删除了“包”集合字段?

So, for your "packages" collection field, do you have a cascade delete on it (just like what you have on your subcontents)? 那么,对于您的“ packages”集合字段,您是否具有级联删除功能(就像子内容中的内容一样)? If you do, then I think it should work. 如果您这样做,那么我认为它应该起作用。 When you delete the root Content, it should perform cascade delete on each subcontent, and each content will then perform cascade delete on the package. 当您删除根目录内容时,它应该对每个子内容执行级联删除,然后每个内容将对程序包执行级联删除。

Does that work? 那样有用吗?

The problem turned out to be caused by the fact that I was flushing and clearing the session after deleting each Package, and due to the circular dependencies in the model not everything was being deleted. 事实证明,该问题是由于删除每个Package之后我正在刷新并清除会话而造成的,并且由于模型中的循环依赖关系,并未删除所有内容。 The flush and clear are required because very large data sets are involved. 需要刷新和清除,因为涉及非常大的数据集。 In the end I changed it so that a set of all entities dependent on the current Package is constructed (which may include other Packages) and then all deleted before calling flush and clear. 最后,我对其进行了更改,以便构造一组依赖于当前Package的所有实体(其中可能包括其他Package),然后在调用flush和clear之前将其全部删除。

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

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