Play Framework 2.0.4 に統合された Ebean 2.7.3 に問題があります。
最初にフレームワークでどのように機能するかを説明しましょう。新しいオブジェクトを作成する場合は、モデル オブジェクトの新しいインスタンスを作成して Web フォームに送信する関数を呼び出します。フォームが送信された後、save() 関数が呼び出されます。この関数は、フォームからの値をバインドし、モデル オブジェクトの別の新しいインスタンスに割り当てます。オブジェクトで update() 関数を呼び出すと、すべてがデータベースに正しく書き込まれます。オブジェクトを更新したい場合も、多少の違いはありますがやり方はほぼ同じです。最初に、オブジェクトがデータベースからロードされ、フォームに送信され、解析されます。違いは、更新されたオブジェクトの元の主キーも解析していることです。次に、update() 関数を呼び出すと、ebean がプライマリ ID を認識し、正しいオブジェクトを更新できるため、すべてが正しく書き込まれます。
問題は、追加すると始まります@Embedded
プロパティをモデルに追加します。新しいオブジェクトを作成して保存し、読み取ることはできますが、更新することはできません。説明したのと同じ原則を使用してオブジェクトを更新しようとすると、OptimisticLockException が発生します。SQL ログを調査したところ、Ebean が SQL の SET 部分のすべてのモデル プロパティと WHERE 句のすべてのプロパティを更新していることがわかりました。これは、Ebean ドキュメントで説明されている楽観的ロック メカニズムに関連していることを知っています。問題は、Ebean が両方の部分 (SET と WHERE) で同じ値を使用していることです。Ebean は元のエンティティを検索できないため、WHERE 部分で古い値を使用できないようです。この結果、データベース内の対応するエンティティが見つからず、更新されずに OptimistickLockException が返されます。@Version
注釈。そこで、updatedStamp という新しいプロパティを作成し、注釈を付けました@Version
。この原則を使用して、update() の呼び出し中に NullPointerException に遭遇しました。
Caused by: java.lang.NullPointerException: null
com.avaje.ebeaninternal.server.core.PersistRequestBean.hasChanged(PersistRequestBean.java:728)
だから私の質問は.@Embedded
モデルでプロパティを使用する適切な方法はありますか? これは Ebean の以前のバージョンで議論されていることは知っていますが、解決策はないようです。
ええと..実際、私はそれを行う方法を1つ見つけました。db からオブジェクトをロードし、このクラス インスタンスを保持すると、そのプロパティを変更して問題なく update() を呼び出すことができます。しかし、実際には、プレイ フレームワークはステートレスであるため、セッション中に元のオブジェクトを保持できないため、これは解決策ではありません。新しいものを作成し、値を入力して保存する必要があります。@Embedded がなければ、これは問題なく動作します。
それを解決する方法の手がかりはありますか?