70

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

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

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

アソシエーションの列がNOTNULLと宣言されている場合、NHibernateはアソシエーションを作成または更新するときに制約違反を引き起こす可能性があります。この問題を防ぐには、inverse = "true"とマークされた多くの値の端(セットまたはバッグ)との双方向の関連付けを使用する必要があります。

これは今のところすべて理にかなっているようです。私が得られないのはこれです:1対多の関係でinverse = trueを使用したくないのはいつですか?

4

3 に答える 3

82

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テーブルに挿入されるため、FK列をnull許容に設定し、その後、Spyテーブルを更新してFKを設定します。この場合、inverse = trueに設定すると、FKは更新されません。

于 2009-07-01T08:02:18.320 に答える
29

高い投票で受け入れられた答えにもかかわらず、私にはそれに対する別の答えがあります。

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

親=>アイテムのリスト
アイテム=>親

Item=>ParentリレーションがParent=>Itemsリレーションに冗長であるとは誰も言いませんでした。アイテムは任意の親を参照できます。

しかし、アプリケーションでは、関係が冗長であることを知っています。リレーションをデータベースに個別に保存する必要はありません。したがって、アイテムから親を指す単一の外部キーに保存することにします。この最小限の情報は、リストと参照を作成するのに十分です。

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

  • 両方の関係に同じ外部キーを使用する
  • 一方(リスト)はもう一方(リスト)と重複しており、オブジェクトを格納するときに無視できることをNHに伝えます。(それはNHが実際に行うことですinverse="true"

これらは、逆に関連する考えです。他には何もありません。それは選択ではなく、正しいマッピングの唯一の方法があります。


スパイの問題:アイテムから親への参照をサポートしたい場合は、まったく別の議論になります。これはあなたのビジネスモデル次第です、NHはこれに関して何の決定もしません。関係の1つが欠落している場合、もちろん冗長性はなく、逆の使用もありません。

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

于 2011-02-04T09:06:18.827 に答える
15

単方向の関連付けが必要な場合、つまり子が親に移動できない場合。その場合、子は親の前に保存されるため、FK列はNULL可能である必要があります。

于 2009-06-30T20:57:52.337 に答える