Search code examples
javajpajpa-annotations

Java - JPA - @Version annotation


How does @Version annotation work in JPA?

I found various answers whose extract is as follows:

JPA uses a version field in your entities to detect concurrent modifications to the same datastore record. When the JPA runtime detects an attempt to concurrently modify the same record, it throws an exception to the transaction attempting to commit last.

But I am still not sure how it works.


Also as from the following lines:

You should consider version fields immutable. Changing the field value has undefined results.

Does it mean that we should declare our version field as final?


Solution

  • 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.