Оптимистическая блокировка с использованием атрибута версии для объекта работает нормально и проста в реализации:
<version property="VERSION" type="int" column="EX_VERSION" />
Сущность имеет свойство следующего типа:
private int VERSION;
public int getVERSION() { return VERSION; }
public void setVERSION(int VERSION) { this.VERSION = VERSION; }
Пока все хорошо. Теперь сервисные методы возвращают объект передачи данных (DTO) для вышеприведенного объекта, который представления отображаются в HTML. Для страниц обновления атрибут VERSION хранится в скрытом HTML-поле и отправляется с формой.
Намерение состоит в том, чтобы использовать свойство version, чтобы гарантировать, что обновление пользователя не будет выполнено, если отображаемая информация сопровождается старой версией.
Контроллер отвечает на запрос пользователей на обновление, вызывая метод службы с DTO, содержащим обновленную информацию (включая свойство версии), а метод службы, в свою очередь, использует объект доступа к данным (DAO) для сохранения изменений:
public void update(SimpleDTO dto) {
SimplyEntity entity = getSimpleDao().load(dto.getId());
copyProperties(dto, entity); // all properties, including VERSION copied to entity
getSimpleDao().update(entity);
}
Проблема в том, что свойство версии, скопированное в сущность с помощью copyProperties (...), не учитывается Hibernate. Я нашел причину в следующем форуме: https://forum.hibernate.org/viewtopic.php?f=1&t=955893&p=2418068
Короче говоря, когда вызывается load (), Hibernate кэширует свойство version в кеше сеанса, и не имеет значения, на какое значение оно впоследствии изменяется. Я согласен с тем, что это правильное поведение, но Боссы дали мне указание передать версию через свойство формы HTML (если есть лучший шаблон для этого, я бы хотел это услышать).
Одним из решений, которое я сейчас изучаю, является исключение объекта из сеанса после того, как его версия была установлена с помощью hibernateTemplate.evict (simpleEntity) до того, как произойдет обновление. Я надеюсь, что это работает, но это не кажется эффективным.
Я бы хотел попросить Hibernate проверить свойство версии на самом экземпляре, а не только в кеше сеанса.
Заранее спасибо за ответы!
-
LES