10

他のエンティティ [質問] のコレクションを含む 1 つのエンティティ [プロジェクト] があります。

「all-delete-orphan」のカスケード属性を使用して関係をマップしました。

私の DB では、リレーションは質問テーブルの project_id (FK) フィールドにマップされています。プロジェクトのない質問は必要ないため、このフィールドを null にすることはできません。

私がそうsession.delete(project)すると、それはできないという例外がスローproject_idされますが、そのフィールドへnullの制約を削除すると、削除はうまくいきます。not-null

誰でもこれを解決する方法を知っていますか?

4

3 に答える 3

11

ドキュメントから直接。これはあなたの問題を正確に説明しています:

ただし、このコード

Parent p = (Parent) session.Load(typeof(Parent), pid);
// Get one child out of the set
IEnumerator childEnumerator = p.Children.GetEnumerator();
childEnumerator.MoveNext();
Child c = (Child) childEnumerator.Current;

p.Children.Remove(c);
c.Parent = null;
session.Flush();

データベースから c を削除しません。p へのリンクを削除するだけです (この場合、NOT NULL 制約違反が発生します)。Child を明示的に Delete() する必要があります。

Parent p = (Parent) session.Load(typeof(Parent), pid);
// Get one child out of the set
IEnumerator childEnumerator = p.Children.GetEnumerator();
childEnumerator.MoveNext();
Child c = (Child) childEnumerator.Current;

p.Children.Remove(c);
session.Delete(c);
session.Flush();

さて、私たちの場合、子はその親なしでは実際には存在できません。したがって、Child をコレクションから削除する場合は、本当に削除したいと考えています。このためには、cascade="all-delete-orphan" を使用する必要があります。

<set name="Children" inverse="true" cascade="all-delete-orphan">
    <key column="parent_id"/>
    <one-to-many class="Child"/>
</set>

編集:

逆のものに関しては、これはSQLの生成方法を決定するだけだと思います。詳細については、このドキュメントを参照してください。

注意すべきことの1つは、持っていますか

not-null="true"

休止状態の構成での多対 1 の関係について?

于 2008-10-14T01:13:20.847 に答える
0

1つの戦略は、データベース内の外部キーをon-delete-cascadeでマークすることです。これにより、NHibernateがデータベースにプロジェクトを削除するように指示するとすぐに、データベース自体が削除をカスケードします。次に、データベース自体がカスケード削除を行うことをNHibernateに通知する必要があります。

于 2008-10-14T00:20:56.957 に答える
-2

削除は最初にプロジェクトで発生し、質問にカスケードしますが、プロジェクトの削除には質問の project_id のヌル化が含まれます (参照整合性のため)。質問オブジェクトの削除で例外は発生しませんが、カスケードは、質問の FK を無効にしようとしています。

Java Persistence with Hibernate」を見ると、delete-orphans ではなく、カスケード型の削除または削除が本当に必要だと思います。

于 2008-10-13T23:49:39.767 に答える