21.4. カスケードと unsaved-value
Parent
が、ある Session
でロードされ、 UI のアクションで何らかの変更が加えられ、update()
を呼んでこの変更を新しいセッションで永続化したいとします。Parent
が子のコレクションを持ち、カスケード更新が有効になっているため、 Hibernate はどの子が新しくインスタンス化されたか、どれがデータベースの既存の行に相当するのかを知る必要があります。Parent
と Child
の両方が Long
型の識別プロパティを生成したとします。Hibernate はどの子が新しいものかを決定するために識別プロパティの値を使います ( 「自動的な状態検出」 を参照してください)。Hibernate3 では、もはやunsaved-value
を明示的に特定する必要がなくなりました。
以下のコードは
parent
と child
を更新し、 newChild
を挿入します:
//parent and child were both loaded in a previous session parent.addChild(child); Child newChild = new Child(); parent.addChild(newChild); session.update(parent); session.flush();
これらは生成された識別子の場合には非常に良いのですが、割り当てられた識別子と複合識別子の場合はどうでしょうか?これは Hibernate が、ユーザーにより割り当てられた識別子を持つ新しくインスタンス化されたオブジェクトと、以前の Session でロードされたオブジェクトを区別できないため、さらに難しくなっています。この場合、Hibernate はタイムスタンプかバージョンのプロパティのどちらを使うか、二次キャッシュに問い合わせます。最悪の場合、行が存在するかどうかデータベースを見ます。