Just put a small example of Hibernate optimistic locking and versioning on github:
Hibernate uses an optimistic locking strategy, based on versioning. This means it tries to avoid taking a lock on data and instead relies on having a version attribute for each entity (assuming you have configured one). When it performs an update, it includes the version attribute in the where clause of the update. If the database row has already been updated by another thread, then no rows will be updated. Since most databases return the number of rows affected by an update statement, Hibernate can check if this value is zero and then throw an exception.
To enable optimistic versioning, simply add a version attribute to each entity. You can choose either a timestamp or a number, but a number may be safer as using a timestamp could fail if multiple computers are updating data and their clocks are out of sync. To add a version attribute, just annotate with @Version.
To demonstrate that attempting to update data with an out of date version does indeed throw an exception, in the example, I’ve created two threads. The first one is given a reference to the data, but it waits until the second thread has updated the data before attempting its own update. You will see that this throws a stale object exception. You can also see from the SQL that the where clause includes the version number.
This article is part of a series on Hibernate. You might be interested in other articles in the series:
Hibernate query limitations and correlated sub-queries
Bespoke join conditions with Hibernate JoinFormula
Inheritance and polymorphism