0

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

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

4

2 に答える 2

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

  2. 次に、関連付けの両側を設定する必要があります

    ひげ.帽子.追加 (redHat);

    redHat.Cat=ひげ;

これでサンプルが機能するはずです。

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

于 2011-01-13T08:32:01.260 に答える
0

I solved the problem by creating a SessionManager which allows me to open a Session, perform any transactions and access any collection proxies within the Session singleton, and then close the Session.

于 2011-01-16T02:59:45.087 に答える