0

次の(簡略化された)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です。

パッケージを削除する前にコンテンツを具体的に (再帰的に) 削除しようとしましたが、同じエラーが発生します。

このエンティティ ツリーが適切に削除されない理由はありますか?

編集:回答/コメントを読んだ後、コンテンツには複数のパッケージを含めることはできず、サブコンテンツには複数の親コンテンツを含めることはできないことに気付きました。残念ながら、それで問題は解決しませんでした。

また、コンテンツから親パッケージに戻る双方向リンクも追加しましたが、これは簡略化されたコードには含まれていません。

4

2 に答える 2

1

ManyToOne マッピングに基づいて正しく理解できれば、1 つのコンテンツに多くのパッケージがあり、上記の簡略化されたコードでコンテンツ クラスから「packages」コレクション フィールドを削除したと思いますか?

それで、あなたの「パッケージ」コレクションフィールドには、カスケード削除がありますか(サブコンテンツにあるものと同じように)?もしそうなら、それはうまくいくはずだと思います。ルート コンテンツを削除すると、各サブコンテンツに対してカスケード削除が実行され、各コンテンツがパッケージに対してカスケード削除が実行されます。

それは動作しますか?

于 2010-06-09T20:03:25.780 に答える
0

この問題は、各パッケージを削除した後にセッションをフラッシュしてクリアしたことが原因であることが判明しました。また、モデルの循環依存関係のために、すべてが削除されたわけではありませんでした。非常に大きなデータ セットが含まれるため、フラッシュとクリアが必要です。最後に、現在のパッケージに依存するすべてのエンティティのセットが構築され (他のパッケージが含まれる場合があります)、フラッシュとクリアを呼び出す前にすべてが削除されるように変更しました。

于 2010-06-18T00:15:38.823 に答える