0

Hibernate 4.1 を使用する Spring 3.1 MVC アプリでは、以下を使用しています。

  • 宣言的なトランザクション管理
  • リクエストごとのセッション
  • ドメイン オブジェクトに「バージョン」プロパティを追加することによる楽観的ロック
  • saveOrUpdate() を使用して切り離されたドメイン オブジェクトを再接続する

ドメイン オブジェクトは、ユーザーが更新できるように、GET 要求中にコマンド オブジェクトとして送信されます。

「オプティミスティック ロックに失敗しました。ネストされた例外は org.hibernate.StaleObjectStateException です: 別のトランザクションによって行が更新または削除されました (または保存されていない値のマッピングが正しくありませんでした)」というエラーが発生しないようにするために、各 JSP ページに「<form:hidden path="version"/>」を含めています。更新は正常に機能しています。

アプリをさらに保護するために、コントローラーに次を追加しようとしています。

@InitBinder
public void initBinder(WebDataBinder dataBinder, HttpServletRequest request) {
  if (request.getMethod().equals("POST")) {
   dataBinder.setDisallowedFields( new String[] {"version"});
  }
}

しかし、そうすると、楽観的ロックに失敗しましたというエラーが表示されます。ネストされた例外は org.hibernate.StaleObjectStateException: 行が別のトランザクションによって更新または削除されました (または、保存されていない値のマッピングが正しくありませんでした)".

私がやろうとしていることがアプローチとして有効かどうか、そして私が間違っていることを誰かが説明してもらえますか?

理想的には、特定の jsp ページによって変更されていないドメイン オブジェクトの主キーとおそらくいくつかのフィールドを保護しようとする必要があると思います。

前もって感謝します。

4

1 に答える 1

0

これは正しくないように見えます。バージョン フィールドのバインドを許可しないでください。バージョン フィールドのバインドを許可しない場合、コマンド オブジェクトには、DB からオブジェクト用に最初に取得したバージョン フィールドがありません。コマンド オブジェクト hibernate を永続化すると、行が他のトランザクションによって既に変更されていると見なされます (db のバージョンとコマンド オブジェクトが一致しないため)。

フィールド (id、バージョン) などを保護しようとすることはできますが、エンティティを最初に保存する時点 (id とバージョンが存在しないと予想される場合) のみですが、更新の場合は元の id とバージョンが存在する必要があります。 .

于 2012-05-25T18:08:19.417 に答える