🔎 Detailed Explanation
🔹 How it works
- When you annotate a field with
@Version
, Hibernate automatically:
✅ Reads the version value when loading the entity.
✅ Checks the version when updating → if the version in the database doesn’t match the version your entity has, Hibernate throws anOptimisticLockException
.
✅ Increments the version value after a successful update.
Typical types for @Version
fields:
int
/Integer
→ incremented by 1 each update.long
/Long
→ incremented by 1.java.sql.Timestamp
→ updated with the current timestamp on each update.
🔹 Example
@Entity
public class Product {
@Id
private Long id;
private String name;
private double price;
@Version
private int version; // automatically managed by Hibernate
}
🔹 What happens on update?
- Suppose you load a
Product
withversion=5
. - If another transaction updates it and increments the version to
6
before you commit:- When you try to update, Hibernate detects a mismatch (
5
vs6
) and throws:
- When you try to update, Hibernate detects a mismatch (
javax.persistence.OptimisticLockException: Row was updated or deleted by another transaction
✅ This prevents lost updates, where concurrent transactions overwrite each other’s changes silently.
🔹 Optimistic vs. Pessimistic locking
- Optimistic (with @Version): no database locks → best for low-contention systems.
- Pessimistic (with explicit locks): database locks to block concurrent modifications.
📊 Benefits of @Version
✅ Protects your data from concurrent updates.
✅ Lightweight → no need for DB locks → better scalability.
✅ Automatic version management by Hibernate.
📌 Key Takeaways
✅ Annotate an entity field with @Version
to enable optimistic locking.
✅ Hibernate uses the version to detect concurrent modifications → avoiding lost updates.
✅ Best for high-read, low-conflict systems needing safe concurrent updates.