[英]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.