2009-07-21 11 views
0

アソシエーションテーブルとcascade = "save-update"を使用して、2つのエンティティ間で多対多リレーションシップを定義しました。NHibernate追加UPDATEクエリの実行

Entity1にはEntity2のリストが含まれ、逆にEntity2にはEntity1のリストが含まれています。このworflowから出力されたSQLが...

  1. コールsession.Save Entity1
  2. にEntity1上のリストにEntity2を追加Entity1とEntity2オブジェクトを作成し、[OKらしい

- > Insertステートメントは、両方のエンティティに対して実行され、次にそれらをリンクする関連テーブルに挿入されたレコードが実行されます。しかし

、I Entity2上最初コールsession.Saveは、リストに追加した場合、その後、何とまったく同じにEntity2のすべての値を設定し、追加のUPDATEステートメントの実行があるEntity1にsession.Saveを呼び出します最初に挿入されました。

問題は発生しませんが、パフォーマンスを低下させる追加のクエリです。私はinverse属性で演奏しましたが、追加の更新文は削除されません。現在どちらの側にも、どのエンティティが保存されていても関連テーブルを更新したいので、inverse = "false"となっています。

アイデア?

答えて

0

回答ありがとうございますが、私は問題を見つけたと考えています。 CRUD操作を実装したエンティティの種類ごとにリポジトリクラスを用意しました。各CRUD操作は自身のセッション/トランザクションを開始し、Save/Update/etcと呼ばれ、トランザクション/セッションを閉じました。

セッション2を呼び出すと、エンティティ2のリストを含むEntity1のsession.Saveがセッション内ですでにEntity2を保持しているため、レコードを更新しようとしていないようです。

一方、Entity2のsession.Saveを呼び出し、別のセッション/トランザクションでEntity1のsession.Saveを呼び出すと、もう一度Entity2を更新する必要があります。私はNHに新しいので、どのオブジェクトを更新する必要があるかをどのように追跡するのかはわかりませんが、セッション間でリセットする必要がありますか?

私のすばらしいDDDリポジトリは、ちょっと役に立たなくなりました。たぶん、リポジトリは、この問題を避けるためにシングルトンセッションなどを使用するべきでしょうか?

ありがとう、 John

+0

セッションはスレッドセーフではないことを覚えておいてください。私はほとんどの人がアプリケーションでaspnetや 'session-per-thread'で 'Session-per-request'を使うと思う。 –

+0

はい、Web上の他の例を見ているでしょう。フォームが開かれるとインスタンス化され(私の場合はリッチクライアントアプリケーション)、フォームが破棄されると閉じられます(セッションを破棄します)。 – John

0

docs: inverse(オプション - デフォルトはfalse):有効にすると、Hibernateはこの結合で定義されたプロパティを挿入または更新しようとしません。

私の提案:いくつかのケースでは2ウェイで追加の更新を防ぐためには、参加する両方のコレクションを更新する必要があります。

Contact c; 
Address a;  
c.Addresses.Add(a); 
a.Contacts.Add(c); 

両側が逆を持っているので、あなたは、おそらく追加のUPDATE文を取得している=偽最初のエンティティの関係リストが空に保存されました。 NHは、すべての関係を更新するために必要と思っていることを実行しているだけです。