← Назад к вопросам

Создавал ли объекты в Hibernate с использованием Version

2.7 Senior🔥 121 комментариев
#ORM и Hibernate#Базы данных и SQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Использование Version в Hibernate

Да, я неоднократно работал с аннотацией @Version в Hibernate при создании и управлении объектами. Это один из ключевых инструментов для реализации оптимистичного блокирования (optimistic locking).

Что такое @Version

@Version — это аннотация, которая добавляется на поле сущности для отслеживания изменений версии объекта. Hibernate автоматически увеличивает значение версии при каждом изменении объекта, что позволяет предотвращать конфликты при одновременном редактировании одной записи несколькими потоками или пользователями.

Практический пример

@Entity
@Table(name = "products")
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "name")
    private String name;
    
    @Column(name = "price")
    private BigDecimal price;
    
    @Version
    @Column(name = "version")
    private Long version;
    
    // getters and setters
}

Как это работает

При создании объекта версия устанавливается в 1:

Product product = new Product();
product.setName("Laptop");
product.setPrice(new BigDecimal("999.99"));
// version автоматически установлена в 1

session.save(product);
// Hiberndate INSERT с version = 1

При каждом обновлении версия увеличивается:

Product product = session.get(Product.class, 1L);
product.setPrice(new BigDecimal("899.99"));
// Hibernate UPDATE с WHERE id = 1 AND version = 1
// После успешного обновления version становится 2

Преимущества

  • Безопасность конкурентности: предотвращает потерю изменений при одновременных обновлениях
  • Автоматизм: Hibernate управляет версией без вашего участия
  • Простота: не требует явных блокировок на уровне базы данных
  • Производительность: оптимистичное блокирование дешевле пессимистичного

Обработка исключений

Если произойдёт конфликт (объект был изменён другим пользователем), Hibernate выбросит StaleObjectStateException:

try {
    Product product = session.get(Product.class, 1L);
    product.setPrice(new BigDecimal("899.99"));
    session.flush();
} catch (StaleObjectStateException e) {
    // Объект был изменён другим потоком/пользователем
    System.out.println("Conflict: object was updated by another user");
    // Перезагрузить объект и повторить операцию
}

Типы версий

  • Numeric: Long, Integer (обычно используются)
  • Timestamp: java.util.Date, java.time.LocalDateTime (для отслеживания времени)
@Version
@Column(name = "last_modified")
private LocalDateTime lastModified;

Best Practices

  • Всегда добавляйте @Version к сущностям, которые обновляются несколькими потоками
  • Обрабатывайте StaleObjectStateException для критичных операций
  • Не используйте пессимистичное блокирование без необходимости
  • Помните, что @Version работает только с @Entity, не с @Embeddable

Это стандартный подход в enterprise-приложениях на Java для обеспечения целостности данных.