我有以下(简化的)休眠实体:
@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。不幸的是,这并没有解决问题。
我还添加了从内容返回到父包的双向链接,这是我在简化代码中遗漏的。