2011-01-12 6 views
0

2つの永続クラスCatHatがあります。猫が多くの異なる帽子を持つことができるように、両者の関係は一対一であり、双方向でマッピングをトラバースすることができると考えてみましょう。念頭に置いてNHibernateでの関連するマッピングの作成と取得

Cat whiskers = new Cat(); 
Hat redHat = new Hat(); 
redHat.Id = 1; // normally assigned by generator but this makes example more explicit 
whiskers.Hats.Add(redHat); 
catService.Save(whiskers); 
hatService.Save(redHat); 

、私はにできないようにする必要があります。各クラスのインスタンス間の関連付けを作成するために、私は私が間違っている場合は、次の操作を行うことができるように、と私を修正しなければなりません次のようにしてredHatに関連付けられているCatを取得しますか?

Hat hat = hatService.FindById(1); // redHat has Id 1 
Cat cat = hat.Cat; // cat should be whiskers 

残念ながら、この手法を使用しようとすると、catはその最後の行でヌルオブジェクトとして表示されます。私はCat.hbm.xmlの1対多のマッピングで何か不足していると思っています。 1を追加すると、「重複マッピング」エラーになったので、私はHat.hbm.xmlにはマッピングを持たない

<set name="Hats" inverse="true"> 
    <key column="Id"/> 
    <one-to-many class="Hat"/> 
</set> 

:ここでは、それが現在のようになります。私はアソシエーションマッピングでHibernate documentationを読んでいますが、それでもこの作業はできません。私は間違って何をしていますか?

Cat.hbm.xml

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
       assembly="Domain" 
       namespace="Domain"> 

    <class name="Cat" table="cats" lazy="true"> 

    <id name="Id"> 
     <generator class="increment" /> 
    </id> 

    <property name="Name" /> 

    <set name="Hats" inverse="true"> 
     <key column="Id"/> 
     <one-to-many class="Hat"/> 
    </set> 

    </class> 

</hibernate-mapping> 

Hat.hbm.xml

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
       assembly="Domain" 
       namespace="Domain"> 

    <class name="Hat" table="hats" lazy="true"> 

    <id name="Id"> 
     <generator class="increment" /> 
    </id> 

    </class> 

</hibernate-mapping> 

編集

:以下

完全なマッピングファイル

問題は、私がCatクラスのISet<Hat>の値を初期化していなかったことだと思います。しかし、私は新しい問題にぶつかってきました。私は組合にアクセスしようとすると、私はこのエラーを取得する:

Could not initialize proxy - no Session.

私は私がこのようなセッションでそれをラップすることができ、私のDAOのメソッド作成した場合、これは容易に回避されるだろう考え出し:

public Cat GetRelatedCat(Hat hat) 
{ 
    Cat cat; 
    using (ISession session = HibernateUtil.GetSessionFactory().OpenSession()) 
    { 
     cat = hat.Cat; 
    } 
    return cat; 
} 

これにより、同じ「セッションなし」エラーが発生します。私は困惑している。

+1

完全なマッピングファイルを表示できますか? – MarioH

+0

@MarioH:投稿を完全なマッピングファイルで更新しました。 –

答えて

0

私は、セッションを開き、任意のトランザクションを実行し、セッションシングルトン内の任意のコレクションプロキシにアクセスしてセッションを閉じることを可能にするSessionManagerを作成することによってこの問題を解決しました。

0
  1. hat.hbmに多対1のエントリを追加する必要があります。 私はうまくいくと思います。

  2. は、その後、あなたは協会

    whiskers.Hats.Add(RedHatの)の両側を設定する必要があります。

    redHat.Cat = whiskers;

これはあなたのサンプルを動作させるはずです。

「セッションがない」という問題は、コレクションプロキシが作成されたセッションでのみ動作するという問題です。したがって、あなたの例では、あなたのHatインスタンスを作成したセッションでのみ動作します。プロキシを別のセッションに接続することは可能ですが、一般的には推奨されません。トランザクション境界やデータの一貫性には複雑な意味があるためです。

+0

Hat.hbmに ''を追加しましたが、永続化しようとすると 'パラメータインデックスが範囲外です '帽子。また、作成されたセッションでコレクションプロキシにしかアクセスできない場合、オブジェクトの関連マッピングを取得するにはどうしたらいいですか? –

+0

これはすでにpkに使用されているため、columnに別の名前を使用する必要があります。 "cat_id"のようなものを使うとうまくいくでしょう。 – MarioH

関連する問題