2

セッションで遅延プロパティを持つオブジェクトを取得しようとし、別のセッションでそれを更新しようとしました。しかし、それはError: No persister for SecUserProxy (actual class is SecUser)で失敗しました

私はNHibernate 3.4を使用しています。私がググったとき、私はそれが修正されたバグであることを知りました。

また、プロキシ オブジェクトが INhibernateProxy を実装している場合、NHibernate を使用してオブジェクトのプロキシを解除できるというこの投稿も見つけました。NHibernate はプラグ可能なプロキシ ファクトリ (Castle、LinFu など) をサポートしなくなったため、内部のものを使用します。内部のものはおそらく INhibernateProxy であると想定しています

したがって、オブジェクトを次のように更新する新しいセッションで次のことを行いました。

 object unprox_obj = Session
     .GetSessionImplementation()
     .PersistenceContext.Unproxy(secUserobj);

これと同じオブジェクトを取得することを見込んでいますが、実際のタイプ、つまり SecUser を使用して、エラーなしで更新できるようにします。ただし、それでもプロキシ オブジェクトが返されます。

何が起こっているのか理解できませんか?

更新: 「secUserobj」が INhibernateProxy ではないことに気付きました。では、別のセッション内でオブジェクトを更新するにはどうすれば INhibernateProxy にできますか?

 if (secUserobj is INHibernateProxy)
 {
     unprox_obj = Session
        .GetSessionImplementation()
        .PersistenceContext.Unproxy(secUserobj);
 }
4

1 に答える 1

2

分離されたオブジェクト(1 つのセッションでロードされ、参照として保持される)は、再結合できます。session.Merge()または使用できますsession.Lock()

9.4.2. 切り離されたオブジェクトの更新

多くのアプリケーションは、1 つのトランザクションでオブジェクトを取得し、それを操作のために UI レイヤーに送信してから、新しいトランザクションで変更を保存する必要があります....

...

...最後のケースは、を使用して回避できますMerge(Object o)。このメソッドは、指定されたオブジェクトの状態を同じ識別子を持つ永続オブジェクトにコピーします。セッションに現在関連付けられている永続インスタンスがない場合は、ロードされます。メソッドは永続インスタンスを返します。指定されたインスタンスが保存されていないか、データベースに存在しない場合、NHibernate はそれを保存し、新しい永続インスタンスとして返します。それ以外の場合、指定されたインスタンスはセッションに関連付けられません。SaveOrUpdate()デタッチされたオブジェクトを使用するほとんどのアプリケーションでは、メソッドとの両方が必要ですMerge()

19.1.4. コレクションとプロキシの初期化

...初期化されていないコレクション(または他のプロキシ)にアクセスする前に
、以前に読み込まれたオブジェクトを新しい ISession にアタッチすることもできます。いいえ、NHibernate は自動的にこれを行いませんし、そうすべきではありません。 ...Merge()Lock()

したがって、切り離された参照を に渡し.Merge()、後で返された(真新しい)オブジェクト参照を操作できます。

MyEntity reAttached = session.Merge<MyEntity>(detached);

これは、分離されたコレクションに触れる前に (上記のように) 行う必要があることに注意してください。

于 2015-05-21T11:34:08.570 に答える