我有一个Play 2.1.3
Java应用程序使用Ebean.我在下面得到了OptimisticLockException.
[OptimisticLockException: Data has changed. updated [0] rows sql[update person set name=? where id=? and email=? and name=? and password is null and created=? and deleted is null] bind[null]]
我明白,这是试图告诉我,当我阅读它和我试图写它之间的记录已经改变了.但是,这种方法中唯一的变化是发生.
public void updateFromForm(Map<String,String[]> form) throws Exception { this.name = form.get("name")[0]; String password = form.get("password")[0]; if (password != null && password.length() != 0) { String hash = Password.getSaltedHash(password); this.password = hash; } this.update(); }
我这样做错了吗?我在zentasks中看到类似的逻辑.另外,我可以看到绑定变量的值吗?
更新:我从控制器内部调用updateFromForm():
@RequiresAuthentication(clientName = "FormClient") public static Result updateProfile() throws Exception { final CommonProfile profile = getUserProfile(); String email = getEmail(profile); Person p = Person.find.where().eq("email",email).findList().get(0); Map<String,String[]> form = request().body().asFormUrlEncoded(); if (p == null) { Person.createFromForm(form); } else { p.updateFromForm(form); } return ok("HI"); }
解决方法
有点晚,但是对于你的案例,
@Version
注释应该是解决方案.我们主要使用java.util.Date,所以它也可以用于确定上一次记录更新的日期,在Play模型中只是:
@Version public java.util.Date version;
在这种情况下,更新语句将仅使用id和版本字段完成 – 特别是在使用大型模型时尤其有用:
update person set name='Bob' where id=1 and version='2014-03-03 22:07:35';
注意:您不需要/应该在每次保存时手动更新此字段,Ebean本身就可以.版本值更改只有当有更新的数据(所以使用obj.update(),其中没有更改不更新版本字段)