Deletes not cascading for self-referencing entities
- by jwaddell
I have the following (simplified) Hibernate entities:
@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. 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.
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.
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. 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.