web-dev-qa-db-ja.com

このエラーはnhibernateで何を意味しますか

突然、nhibernateを使用して多数の更新を行うと、このエラーが発生します。

行が別のトランザクションによって更新または削除されました(または未保存-値のマッピングが正しくありませんでした):[MyDomainObject]

エラーには追加情報はありません。根本的な問題を特定するのに役立つ推奨される方法はありますか、または誰かがこのエラーが何を示しているか、または周りの症状であるかについてより良い説明を私に与えることができますか?.

いくつかの追加情報

オブジェクトを見ると、すべてのデータが正常に見え、IDなどがあります。 。

これはasp.net-mvcWebサイトからの単一の呼び出しスタックで実行されているため、同時実行性に関して心配するスレッドの問題はないと思います。

22
leora

これは、同じデータにアクセスする複数のトランザクションがあるため、同時実行の問題が発生することを意味します。データアクセス処理を改善する必要があります。おそらく複数のスレッドからデータを更新し、変更されたデータを最初にキューにシンジケートして、データベースへのすべてのアクセスを処理します。

14
Femaref

NHibernateにはオブジェクトがあります。それをtheObjectと呼びましょう。 theObject.Idの値は42です。 NHibernateは、オブジェクトがダーティであることに気づきます。オブジェクトのIDは、整数の主キーの場合はゼロ(0)である未保存の値とは異なります。そのため、NHibernateは更新ステートメントを発行しますが、行は更新されません。つまり、Id42であるそのタイプのオブジェクトの行はデータベースにありません。そのため、NHibernateが知らないうちにオブジェクトが削除されました。これは、別のトランザクション内で発生する可能性があります(たとえば、スレッドの問題がある場合)、または誰か(または別のアプリケーション)がSQLを使用してデータベースに対して直接行を削除/変更した場合に発生する可能性があります。

もう1つの可能性は、保存されていない値が間違っていることです。例えば-1を使用して未保存のエンティティを示していますが、マッピングの未保存の値はゼロです。アプリケーションは通常、その音から動作しているため、これは起こりそうにありません。 unsaved-valueが間違っていた場合、NHibernateはUPDATEを発行するはずのときにINSERTステートメントを発行していたため、エンティティをデータベースに保存できませんでした。

23
James Kovacs

古い投稿ですが、私の情報が誰かに役立つことを願っています。新しいオブジェクトを追加した後、関連付けを永続化する場合にのみ、同様のエラーが発生していました。エラーの形式は次のとおりです。

NHibernate.StaleObjectStateException:行が別のトランザクションによって更新または削除されました(または未保存の値のマッピングが正しくありませんでした)[My.Entity#0]

私の識別子のプロパティである最後のゼロに注意してください。 SQL Server(ジェネレーターclass = native)でID仕様を使用していたので、キー0で保存しようとしてはいけません。 xmlの未保存の値を変更していなかったため、問題が何であるかわかりませんでした。何らかの理由で、NHibernateは、新しいオブジェクトの保存(および次のキーIDの取得)ではなく、キー値0を使用して更新を実行しようとしていました。

結局、原因は、コンストラクターで新しいオブジェクトのバージョン番号を1に初期化していたことであることがわかりました。私の識別子プロパティがゼロであったとしても、何らかの理由でNHibernateは、保存されていない一時インスタンスとして識別するために、ゼロのバージョンプロパティも探していました。 「NHibernateinAction」という本は、実際には120ページでこれについて言及していますが、何らかの理由で、バージョン番号1で通常どおり永続化するとオブジェクトは正常であり、関連付けによって新しいオブジェクトを保存した場合にのみ失敗します。

したがって、バージョン値を設定しないようにしてください(ゼロまたはnullのままにします)。

6
David Fidge

データは大丈夫だと言いますが、たとえばIDを自己生成としてマッピングしているかどうかを確認してください。まったく同じ問題が発生しましたが、IDが0とは異なるオブジェクトを送信していました。

それが役に立てば幸い!

1
C3PO

私の問題はこれでした:

[Bind(Include="Name")] EventType eventType

になるはずだった:

[Bind(Include="EventTypeId,Name")] EventType eventType

他の回答が示唆しているように、nhibernateはエンティティのIDとしてゼロを使用していました。

0
rocktheartsm4l

テーブルにトリガーがある場合は、それが理由である可能性があります。この場合、その中に追加します

SET ROWCOUNT 0; SET NOCOUNT ON;

0
scode102