Для чего нужна аннотация @Version в JPA?

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

Ответ

Аннотация @Version в JPA предназначена для реализации механизма оптимистичной блокировки (optimistic locking). Этот подход разрешает конфликты параллельных изменений данных на уровне приложения, а не базы данных.

Зачем это нужно? Чтобы безопасно обрабатывать сценарии, когда несколько пользователей или процессов одновременно читают, а затем пытаются обновить одну и ту же запись.

Как это работает (шаги):

  1. Чтение: Транзакция A и транзакция B читают сущность Product с version=1.
  2. Изменение и сохранение A: Транзакция A изменяет сущность и вызывает entityManager.merge(). Hibernate выполняет UPDATE product SET ..., version=2 WHERE id=123 AND version=1. Успешно, version в БД становится 2.
  3. Попытка сохранения B: Транзакция B (все еще работающая со «старой» копией, где version=1) пытается сохранить свои изменения. Запрос UPDATE ... WHERE id=123 AND version=1 не найдет строк для обновления, так как текущая версия в БД уже 2.
  4. Исключение: Hibernate фиксирует 0 обновленных строк и выбрасывает OptimisticLockException. Транзакция B должна обработать это исключение (например, повторить операцию с актуальными данными).

Типичное использование:

@Entity
public class Document {
    @Id
    private Long id;
    @Version
    private Integer version; // Используется для оптимистичной блокировки
    private String content;
}

Ключевое преимущество: Высокая производительность, так как блокировки на уровне БД не удерживаются долго.