2009-06-30 12 views
69

私は、Hibernateのinverse属性でグリップを取得しようとしていますが、それは概念的に難しいものの1つにすぎません。NHibernate/Hibernate OneToMany関係でinverse = falseを使用するのはいつですか?

多対多のマッピングを使用しているChildオブジェクトのコレクションを持つ親エンティティ(たとえばParent)がある場合、マッピングでinverse = trueを設定すると、Hibernateは、もう片方の側(子)はテーブル内の外部キー参照を維持するために自身を更新する責任があります。

これを行うと、あなたのコード内のコレクションにChildrenを追加し、親(カスケード・オール・セットで)を保存すると2つの利点があるように見えます:you save an unneccessary hit on the database(逆セットなしで、Hibernateは2つの場所)FK関係を更新するために、公式のドキュメントによると:それは を作成するか、関連付けを更新するとき

関連の列が NOT NULLと宣言されている場合は、NHibernateのは 制約違反が発生することがあります。 にこの問題を回避するには、逆=「真」としてマークされ 多くの大切なエンド(セットまたは袋) で 双方向関連を使用する必要があります。

このすべては、これまで意味をなさないようです。私が得ないのはこれです:あなたはいつですかNOT 1対多の関係でinverse = trueを使いたいですか?

答えて

81

Matthieuによると、inverse = trueを設定したくない場合は、子供が知識を持たない場合など、自分自身を更新する責任を子供が持つことができない場合ですその親の

現実の世界を試し、そして全く不自然な例ましょう:私たちは多対1の関係が含まれていないため、

<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> 

Spymastersはスパイを持つことができますが、スパイは、彼らのspymasterが誰であるか知っていることはありませんスパイクラスでまた、(便利に)スパイが不正に変わる可能性があるため、スパイマスターと関連付ける必要はありません。次のように私たちは、エンティティを作成することができます

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テーブルとスパイのテーブルに挿入、およびしまうので、NULL可能であることをFK列を設定しますそのような場合にのみ後に、それはそれを希望Spyテーブルを更新してFKを設定します。この場合、inverse = trueを設定すると、FKは決して更新されません。

+0

これは私のためには機能しませんでした。アップデートを実行することはありません。挿入するだけです。 – BradLaney

14

一方向の関連付けが必要な場合、つまり、子が親にナビゲートできない場合。その場合、子が親の前に保存されるため、FK列はNULLABLEになります。

28

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

これらの関係でクラス図を考えてみません:

 
Parent => list of Items 
Item => Parent 

をこれまでアイテムが=>親の関係は、親=>アイテムの関係に冗長であることを、言いました。アイテムは任意の親を参照できます。

しかし、あなたのアプリケーションでは、あなたはその関係が冗長であることを知っています。リレーションシップをデータベースに別々に格納する必要はありません。したがって、それを単一の外部キーに格納することを決めました。これは、項目から親を指しています。この最小限の情報はリストを作成するのに十分です。

あなたはNHでこれをマップするためにやらなければならないことは、次のとおりです。

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

これらは逆に関連する考えです。他に何もない。これは選択肢ではなく、正しいマッピング方法は1つだけです。


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

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

+0

私はその答えが受け入れられた答えよりも理解できることを発見しました – r3try

+0

私の[答え](http://stackoverflow.com/a/6951546/221708)よりもずっと簡単でポイントに。 –

関連する問題