OptimisticLockException exception with Ebean and Play Framework 2

I use Ebean with Play Framework 2, and sometimes it crashes with this type of 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]]] 

This happens when several participants start accessing the database.

So the manager class:

 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(); } } 

save () and update () are used instead of @PrePersist annotations since Ebean does not support it. As I know, the @Version annotation always introduces an optimistic locking mode, so I'm starting to use this trick. I know what Optimistick lock is, but how should this situation be resolved when many participants have to change the same db record, where the last modification wins?

+7
source share
2 answers

Decision:

Problem. Saving a separate EBean model directly from the playback form raises either an OptimisticLockException, or when using @Version it throws a NullpointerException.

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

Decision. The form must support the delivery of the object from the database before contacting the request parameters. The parameters found in the query should then overwrite the corresponding properties of the object. Maybe call fill () before bindFromRequest ():

 Form<Venue> form = form(Venue.class).fill(Venue.find.byId(id)).bindFromRequest(); form.get().update(id); 
+15
source

I solved this OptmistLockException problem by simply passing the object identifier to the controller when trying to update. To prevent the user from changing the value, the value was transmitted as a hidden field.

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

On the controller side, I check to see if the resulting form has errors. In the negative case, I update the attached object in the form.

  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(); } } 
+2
source

All Articles