Проблема обновления существующей записи при использовании аннотации @Version для оптимистической блокировки.
Наличие таблицы (скажем, "X") с этим подходом аннотации:
@Id() @GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name="calcid")
private int calcId;
@Version @Column(name="version")
protected Integer version;
Использование этогоподход (pp - поставщик одноэтапной устойчивости):
Выборка записей:
Session session = [my persistency provider singleton].openSession();
session.beginTransaction();
List<X> xx = session.createQuery("from x",X.class).getResultList();
pp.closeSession();
return xx
Изменение записи x из списка xx и помещение этого (и только этого) в список отправленныхк процедуре слияния (не путайте со списком - в нем есть только одна запись - измененная, но таким образом я готов к объединению нескольких записей):
Слияние одной записи
Session session = [my persistency provider singleton].openSession();
session.beginTransaction();
xx.forEach(x -> { session.merge(x);});
try {
session.getTransaction().commit();
} catch (OptimisticLockException e) {
pp.closeSession();
throw e;
}
pp.closeSession();
Хотя я могу проверить @Id непосредственно перед слиянием и увидеть, что он совпадает с исходно извлеченной записью, в результате получается новая запись с новым идентификатором.
Если я просто удаляю аннотацию версии (и поле версии), слияние ведет себя так, как ожидалось (тот же код, что и выше, только без @Version и version-column), обновляя существующую запись.
Обратите внимание, что, хотя проблема, по-видимому, связана с @ Version'ing, включенным в оптимистический подход блокировки, в приведенном выше примере задействован только один сеанс.
Кажется, что только @version заставляет Hibernate рассмотретьисходный экземпляр как новый (даже если идентификатор тот же) и, следовательно, создание нового с новым идентификатором.
Впервые в Hibernate, поэтому TIA для любой помощи!
Использование MariaDB (FKA MySQL) версии 10. Hibernate 5 и это cfg:
<?xml version="1.0" encoding="UTF-8"?>
<!-- <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 5.3//EN" "http://www.hibernate.org/dtd/hibernate-configuration-5.3.dtd"> -->
<!DOCTYPE hibernate-configuration SYSTEM "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd" PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN">
-<hibernate-configuration>
-<session-factory>
<!-- <property name="hbm2ddl.auto">update</property> -->
<property name="hbm2ddl.auto">update</property>
<property name="dialect">org.hibernate.dialect.MySQL8Dialect</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="connection.username">xxx</property>
<property name="connection.password"/>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.show_sql">false</property>
<mapping class="niels.test.Test"/>
</session-factory>
</hibernate-configuration>
С уважением