NHibernate / Hibernate OneToMany 関係で inverse=false を使用するのはどのような場合ですか?

StackOverflow https://stackoverflow.com/questions/1061179

質問

私は Hibernate の inverse 属性を理解しようとしてきましたが、それは概念的に難しいものの 1 つにすぎないようです。

私が得た要点は、親エンティティ(例:Parent) を使用した Child オブジェクトのコレクションを持つ 1対多 マッピングでは、マッピングで inverse=true を設定すると、Hibernate に「反対側 (子) がテーブル内の外部キー参照を維持するために自身を更新する責任がある」と指示されます。

これを行うと、コード内のコレクションに子を追加し、(cascade-all を設定して) 親を保存する場合に 2 つの利点があるようです。 データベースに不必要なヒットを保存してしまう (逆セットがないと、Hibernate は FK 関係を更新する場所が 2 つあると考えるため)、公式ドキュメントによると、次のようになります。

協会の列がヌルではないと宣言されている場合、nhibernateは協会を作成または更新するときに制約違反を引き起こす可能性があります。この問題を防ぐには、逆= "true"としてマークされた多くの価値のある終わり(セットまたはバッグ)との双方向の関連性を使用する必要があります。

これまでのところ、これはすべて意味があるように思えます。私が理解できないのはこれです:いつしますか ない 1 対多の関係で inverse=true を使用したいですか?

役に立ちましたか?

解決

Matthieu が言うように、inverse = true を設定したくない唯一のケースは、子が親についての知識を持たない場合など、子が自分自身を更新する責任を負うのが理にかなわない場合です。

まったく不自然な例を実際に試してみましょう。

<class name="SpyMaster" table="SpyMaster" lazy="true">
  <id name="Id">
    <generator class="identity"/>
  </id>
  <property name="Name"/>
  <set name="Spies" table="Spy" cascade="save-update">
    <key column="SpyMasterId"/>
    <one-to-many class="Spy"/>
  </set>
</class>

<class name="Spy" table="Spy" lazy="true">
  <id name="Id">
    <generator class="identity"/>
  </id>
  <property name="Name"/>
</class>

スパイマスターにはスパイを含めることができますが、スパイ クラスに多対 1 の関係が含まれていないため、スパイは自分のスパイマスターが誰であるかを知りません。また、(都合の良いことに)スパイは不正者になる可能性があるため、スパイマスターと関連付ける必要はありません。次のようにエンティティを作成できます。

var sm = new SpyMaster
{
    Name = "Head of Operation Treadstone"
};
sm.Spies.Add(new Spy
{
    Name = "Bourne",
    //SpyMaster = sm // Can't do this
});
session.Save(sm);

このような場合、sm を保存する操作によって SpyMaster テーブルと Spy テーブルに挿入され、その後初めて Spy テーブルが更新されて FK が設定されるため、FK 列を NULL 可能に設定します。この場合、inverse = true に設定すると、FK は決して更新されません。

他のヒント

高い投票で受け入れられた回答にもかかわらず、私はそれに対して別の答えを持っています。

次の関係を持つクラス図を考えてみましょう。

Parent => list of Items
Item => Parent

誰でもない これまで アイテム => 親の関係は、親 => アイテムの関係に対して冗長であると述べました。項目は任意の親を参照できます。

しかし、あなたのアプリケーションでは、 関係が冗長であることを知っていますか. 。リレーションをデータベースに個別に保存する必要がないことがわかります。そこで、次の場所に保管することにしました。 単一の外部キー, 、項目から親を指します。リストを作成するには、この最小限の情報で十分です そして リファレンスバック。

これを NH にマッピングするために必要なのは、次のことだけです。

  • 両方のリレーションに同じ外部キーを使用します
  • 一方 (リスト) が他方に対して冗長であり、オブジェクトを保存するときに無視できることを NH に伝えます。(それがNHが実際にやっていることです) inverse="true")

これらはインバースに関連する思考です。他には何もありません。これは選択ではなく、正しいマッピングの方法は 1 つだけです。


スパイ問題:全く違う議論です もし 項目から親への参照をサポートしたいと考えています。これはあなたのビジネスモデル次第であり、NH はこれに関していかなる決定も下しません。関係の 1 つが欠落している場合、当然、冗長性はなくなり、逆関数は使用されなくなります。

悪用: メモリに冗長性がないリストに対して inverse="true" を使用すると、リストは保存されません。inverse="true" を指定する必要がある場合に指定しない場合、NH は冗長情報を 2 回保存する可能性があります。

一方向の関連付けが必要な場合、つまり子は親に移動できないということです。その場合、子は親よりも前に保存されるため、FK 列は NULLABLE である必要があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top