У меня есть простая сущность с одним атрибутом и версия для оптимизации c режим блокировки.
@Entity
@Table(name = "PERSON")
public class Person implements Serializable {
@Id
private Integer id;
@Version
@Column(name = "VERSION")
private Long version;
@Column(name = "NAME")
private String name;
}
Я хочу работать с экземпляром в отдельном состоянии.
Шаг 1. Я открываю сессию, как-то загружаю экземпляр, закрываю сессию.
Session session = ... ;
Person person = session.get(Person.class, 1);
session.close();
Шаг 2. Я изменяю значение атрибута person в отдельном состоянии.
person.setName("Bob");
Шаг 3. Я открываю новый сеанс, объедините экземпляр и попросите сеанс вернуть мне экземпляр с помощью метода .get
Session session = ... ;
person = session.merge(person);
// something happen there
// and then we decide to get our instance from session
person = session.get(Person.class, 1);
System.out.println(person.getVersion()); // result is 0
Шаг 4. Я делаю то же самое, что и на шаге 3, но с запросом.
Session session = ... ;
person = session.merge(person);
// something happen there
// and then we decide to get our instance from session
Query<Person> query = session.createQuery("from Person p where p.id = :id", Person.class);
query.setParameter("id", 1L);
person = query.list().iterator().next();
System.out.println(person.getVersion()); // result is 1
Итак, какая здесь разница? Оба случая затрагивают базу данных, но только второй случай выполняет обновление версии (и это поведение кажется мне неправильным, потому что, если я повторю шаг 4 два раза, я получу исключение DbConcurrentModificationException). Где я что-то пропустил? Где я могу прочитать об этом? Почему версия обновляется не во время гриппа sh?
Hibernate 5.4.12.Final
Спасибо за помощь!