2つの永続クラスCat
とがありHat
ます。猫は多くの異なる帽子を持つことができ、マッピングを両方向にトラバースできるように、2つの間の関係が双方向に1対多であると想像してみましょう。各クラスのインスタンス間に関連付けを作成するには、次のことを実行できます。間違っている場合は修正します。
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はその最後の行でnullオブジェクトになります。Cat.hbm.xmlの1対多のマッピングに何かが欠けていると思います。少なくとも、それがそれほど単純なものであることを願っています。現在の外観は次のとおりです。
<set name="Hats" inverse="true">
<key column="Id"/>
<one-to-many class="Hat"/>
</set>
Hat.hbm.xmlにマッピングを追加すると、「重複マッピング」エラーが発生したため、マッピングがありません。アソシエーションマッピングに関するHibernateのドキュメントを読みましたが、それでもこれを機能させることができません。私は何が間違っているのですか?
以下の完全なマッピングファイル:
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>
編集
問題はISet<Hat>
、Catクラスの値を初期化していないことだと思います。しかし、私は新しい問題に遭遇しました。アソシエーションにアクセスしようとすると、次のエラーが発生します。
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;
}
これにより、同じ「セッションなし」エラーが発生します。私は困惑しています。