But still I am not sure how it works?
Let’s say an entity MyEntity has an annotated version property:
@Entity
public class MyEntity implements Serializable {
@Id
@GeneratedValue
private Long id;
private String name;
@Version
private Long version;
//...
}
On update, the field annotated with @Version will be incremented and added to the WHERE clause, something like this:
UPDATE MYENTITY SET ..., VERSION = VERSION + 1 WHERE ((ID = ?) AND (VERSION = ?))
If the WHERE clause fails to match a record (because the same entity has already been updated by another thread), then the persistence provider will throw an OptimisticLockException.
Does it mean that we should declare our version field as final
No but you could consider making the setter protected as you’re not supposed to call it.