21.3. ライフサイクルのカスケード

明示的に save() をコールするのは面倒ですが、カスケードを使って対処することができます
<set name="children" inverse="true" cascade="all">
    <key column="parent_id"/>
    <one-to-many class="Child"/>
</set>
これにより先ほどのコードを以下のように単純化します:
Parent p = (Parent) session.load(Parent.class, pid);
Child c = new Child();
p.addChild(c);
session.flush();
同様に Parent を保存または削除するときに、子を一つずつ反復して扱う必要はありません。以下は p を削除し、そしてデータベースからその子をすべて削除します。
Parent p = (Parent) session.load(Parent.class, pid);
session.delete(p);
session.flush();
しかし、以下のコードは:
Parent p = (Parent) session.load(Parent.class, pid);
Child c = (Child) p.getChildren().iterator().next();
p.getChildren().remove(c);
c.setParent(null);
session.flush();
データベースから c を削除しません。この場合、 p へのリンクを削除するのみで、NOT NULL 制約違反を引き起こします。明示的にChilddelete()する必要があります。
Parent p = (Parent) session.load(Parent.class, pid);
Child c = (Child) p.getChildren().iterator().next();
p.getChildren().remove(c);
session.delete(c);
session.flush();
今このケースでは実際に Child が親なしでは存在できないようになりました。そのため、コレクションから Child を取り除く場合、これも削除します。そのためには cascade="all-delete-orphan" を使わなければなりません。
<set name="children" inverse="true" cascade="all-delete-orphan">
    <key column="parent_id"/>
    <one-to-many class="Child"/>
</set>
コレクションのマッピングで inverse="true" と指定しても、コレクションの要素の反復によって、依然カスケードが処理されます。そのため、カスケードでオブジェクトを保存、削除、更新する必要がある場合は、それをコレクションに追加しなければなりません。単に setParent() を呼ぶだけでは不十分です。