Оптимистическая блокировка с использованием атрибута version для объекта работает отлично и легко реализуется:
<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);
}
Проблема заключается в том, что свойство version, скопированное в объект copyProperties (...), не поддерживается Hibernate. Я проследил причину на следующем форуме: https://forum.hibernate.org/viewtopic.php?f=1&t=955893&p=2418068
Вкратце, когда вызывается load(), Hibernate кэширует свойство версии в кеше сеанса, и не имеет значения, для чего впоследствии оно изменилось. Я согласен с тем, что это правильное поведение, но мне поручено Bosses передать версию через свойство HTML-формы (если для этого есть лучший образец, я бы хотел его услышать).
Одно из решений, которое я изучаю сейчас, - это выдворить сущность из сеанса после того, как она была установлена с помощью hibernateTemplate.evict(simpleEntity) до того, как произойдет обновление. Я надеюсь, что это сработает, но это не кажется эффективным.
Я хотел бы попросить Hibernate проверить свойство версии на самом экземпляре, а не только на кеш сеанса.
Заранее благодарим за ответы!
- LES