Yes. They work together, you can use @Version
without LockMode.OPTIMISTIC
but you cannot use LockMode.OPTIMISTIC
without @Version
.
With optimistic locking, whenever you modify an entity then the version column of the entity is incremented. When an entity is saved it ensures that the version column is what it was when the entity was first read and, if not, it throws an OptimisticLockException
(which typically results in a restart of the transaction).
There could be times when you need to "change" an entity without really changing it. This tends to be pretty rare. For example, imagine there a Foo
object which has a mode
field and a Bar
object which has a volume
field. If the mode
is LOUD
the volume
can be 0-100. If the mode
is QUIET
the volume
can only be 0-10.
It's possible with optimistic locking that you can get in a bad state if one user changes the mode
(from LOUD
to QUIET
) at the same time another user changes the volume
(from 5 to 50). This is because the first user increments and checks the version column on the Foo
entity and the second user increments and checks the version column on the Bar
entity.
One solution for this would be for your changeVolume
function to obtain a LockMode.OPTIMISTIC
lock on the Foo
object. This tells Hibernate that even though this function doesn't modify the Foo
object it still needs to increment and check the version field.