次の(簡略化された)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;
}
}
そのため、1 つの「トップ」コンテンツを持つ 1 つのパッケージがあります。最上位のコンテンツは、カスケードが ALL に設定された状態でパッケージにリンクします。トップ コンテンツには多くの「サブ」コンテンツが含まれる場合があり、各サブコンテンツには独自のサブコンテンツが多数含まれる場合があります。各サブコンテンツには親パッケージがあり、これは最上位のコンテンツと同じパッケージである場合もそうでない場合もあります (つまり、コンテンツとパッケージの多対 1 の関係)。
関係は、ManyToOne (パッケージからコンテンツへ) および ManyToMany (コンテンツからサブコンテンツへ) である必要がありますが、現在テストしているケースでは、各サブコンテンツは 1 つのパッケージまたはコンテンツのみに関連しています。
問題は、パッケージを削除してセッションをフラッシュすると、 table の外部キー制約に違反していることを示す Hibernate エラーが発生subcontents
し、特定のcontent_id
ものが table からまだ参照されていることsubcontents
です。
パッケージを削除する前にコンテンツを具体的に (再帰的に) 削除しようとしましたが、同じエラーが発生します。
このエンティティ ツリーが適切に削除されない理由はありますか?
編集:回答/コメントを読んだ後、コンテンツには複数のパッケージを含めることはできず、サブコンテンツには複数の親コンテンツを含めることはできないことに気付きました。残念ながら、それで問題は解決しませんでした。
また、コンテンツから親パッケージに戻る双方向リンクも追加しましたが、これは簡略化されたコードには含まれていません。