7

私はPlayFramework2でEbeanを使用していますが、このような種類のOptimisticLockExceptionが発生することがあります。

play.core.ActionInvoker$$anonfun$receive$1$$anon$1: Execution exception [[OptimisticLockException: Data has changed. updated [0] rows sql[update manager set modification_time=?, session_id=?, expiration_date=? where id=? and rating=? and creation_time=? and modification_time=? and name=? and surname=? and login=? and password_hash=? and email=? and session_id=? and expiration_date=?] bind[null]]]

これは、データベースへのアクセスを開始するアクターが少ない場合に発生します。

したがって、Managerクラスは次のとおりです。

public class Manager extends Model {
@Getter @Setter
Long id;

@Getter @Setter
private String name;

@Getter @Setter
private String surname;

@Column(unique = true)
@Getter @Setter
private String login;

@Getter @Setter
private String passwordHash;

@Getter @Setter
private String email;

@Embedded
@Getter @Setter
private ManagerSession session;

@Getter
private Timestamp creationTime;

@Getter
private Timestamp modificationTime;

@Override
public void save() {
    this.creationTime       = new Timestamp(System.currentTimeMillis());
    this.modificationTime   = new Timestamp(System.currentTimeMillis());
    super.save();
}

@Override
public void update() {
    this.modificationTime   = new Timestamp(System.currentTimeMillis());
    super.update();
}

}

Ebeanはサポートしていないため、代わりに@PrePersistアノテーションを使用するsave()およびupdate()フック。私が知っているように、@ Versionアノテーションは常に楽観的なロックモードをもたらすので、私はそのようなトリックを使い始めます。Optimistickロックとは何かを知っていますが、多くのアクターが同じdbレコードを変更する必要がある場合、最後の変更が優先される場合、この状況をどのように解決する必要がありますか?

4

2 に答える 2

15

解決:

問題:切り離されたEBeanモデルをPlayフォームから直接保存すると、OptimisticLockExceptionが発生するか、@Versionを使用するとNullpointerExceptionが発生します。

Form<Venue> form = form(Venue.class).bindFromRequest();
form.get().update(id); // this causes the exception

解決策:フォームは、リクエストパラメータからバインドする前に、データベースからのオブジェクトの提供をサポートする必要があります。リクエストで見つかったパラメータは、オブジェクトの関連するプロパティを上書きする必要があります。おそらく、bindFromRequest()の前にfill()を呼び出します。

Form<Venue> form = form(Venue.class).fill(Venue.find.byId(id)).bindFromRequest();
form.get().update(id);
于 2012-10-28T13:50:09.943 に答える
2

更新しようとしたときにエンティティIDをコントローラーに渡すだけで、このOptmistLockExceptionの問題を解決しました。ユーザーが値を変更できないようにするために、値は非表示フィールドとして渡されました。

 <input type="hidden" name="id" value="@formVar(<identifierVariable>).value"/>

コントローラー側では、受け取ったフォームにエラーがないか確認します。否定的なケースでは、フォームの添付エンティティを更新します。

 public static Result update() {
     Form<Entity> filledForm = form.bindFromRequest();
     if ( filledForm.hasErrors() ) {
        flashError("app.oh_snap", "app.change_things");
     } else {
        Entity entity = filledForm.get();
        entity.update();
     }
 }
于 2013-04-18T12:48:06.883 に答える