Какую роль выполняет аннотация @Version в JPA/Hibernate?

«Какую роль выполняет аннотация @Version в JPA/Hibernate?» — вопрос из категории Hibernate, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Аннотация @Version в JPA реализует оптимистичную блокировку (optimistic locking). Она предотвращает конфликты «lost update», когда несколько транзакций пытаются изменить одну и ту же сущность.

Принцип работы:

  1. У сущности есть специальное поле (например, version), помеченное @Version.
  2. При каждом обновлении сущности JPA-провайдер (Hibernate) автоматически увеличивает значение этого поля.
  3. При операции UPDATE в SQL-запрос добавляется условие WHERE id=? AND version=?. Если версия в БД изменилась (другая транзакция уже обновила запись), условие не срабатывает и количество обновленных строк равно 0.
  4. Hibernate отслеживает это и выбрасывает OptimisticLockException.

Пример сущности:

@Entity
public class Account {
    @Id
    private Long id;
    private BigDecimal balance;

    @Version
    private Long version; // Автоматически управляется Hibernate

    // Геттеры и сеттеры
}

Важные правила:

  • Тип поля: Long, Integer, short, int, java.sql.Timestamp.
  • Не изменяйте вручную: Значение управляется исключительно JPA-провайдером.
  • Проверка: Проверка версии обычно происходит при flush() или в конце транзакции.