Предположим, у меня есть сущность, определенная следующим образом:
@Entity
public class MyEntity {
@Id
@GeneratedValue
private Integer id;
@Column
private String name;
@Version
int version;
// Getters + setters
}
Предположим, у меня также есть служба (API REST или что-то подобное), которая позволяет пользователю получать информацию об этой сущности.Возвращает идентификатор, текущее имя и текущую версию.Существует также другая служба, которая позволяет пользователю обновлять имя объекта.Он принимает идентификатор, имя обновления и версию в качестве входных параметров.Таким образом, сущность может быть обновлена путем создания нового объекта и использования слияния:
public MyEntity update(EntityManager em, int id, String name, int version) {
MyEntity entity = new Entity();
entity.setId(id);
entity.setName(name);
entity.setVersion(version);
return em.merge(entity);
}
В качестве альтернативы его можно обновить, извлекая его из базы данных и обновляя только соответствующие поля:
public MyEntity update(EntityManager em, int id, String name, int version) {
MyEntity entity = em.find(MyEntity.class, id);
entity.setName(name);
entity.setVersion(version);
return entity;
}
Мое тестирование говорит мне, что в Hibernate 5.3 первый сценарий вызовет исключение OptimisticLockException (с сообщением Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)
), если предоставленная версия не совпадает с тем, что находится в базе данных.Однако второй сценарий работает нормально, и имя обновляется независимо от предоставленной версии.
Я также пробовал это с DataNucleus 5.1.9, и ни один из сценариев не выдает исключение, а имя обновляется независимо от версии.поставляется в обоих случаях.
Так что я думаю, что либо есть ошибка в Hibernate, либо DataNucleus, один из них не соответствует спецификации JPA, либо в спецификации не указано, как это должно работать?
Я пытался найти окончательный ответ на этот вопрос, но не смог этого сделать.Может кто-нибудь подтвердить, как, согласно спецификации JPA, должна работать оптимистическая блокировка, когда дело доходит до обновления сущностей с номером версии, предоставляемым извне?