2009-09-14 3 views
12

Оптимистическая блокировка с помощью атрибута версии для объекта работает отлично и легко реализовать:Как использовать оптимистичное свойство блокировки Hibernate на передней панели?

<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 и отправляется с формой.

Цель состоит в том, чтобы использовать свойство версии, чтобы убедиться, что обновление пользователя не удастся, если отображаемая информация сопровождается старой версией.

Контроллер отвечает на запрос обновления пользователей, вызывая метод службы с помощью 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 кэширует свойство версии в кеше сеанса, и не имеет значения, для чего впоследствии изменяется значение. Я согласен с тем, что это правильное поведение, но мне поручено Bosses передать версию через свойство HTML-формы (если для этого есть лучший образец, я бы хотел его услышать).

Одно из решений, которое я изучаю сейчас, заключается в выводе сущности из сеанса после того, как его версия была установлена ​​с использованием hibernateTemplate.evict (simpleEntity) до того, как произойдет обновление. Я надеюсь, что это сработает, но это не кажется эффективным.

Я хотел бы попросить Hibernate проверить свойство версии на самом экземпляре, а не только на кеш сеанса.

Заранее благодарим за ответы!

- LES

+3

evict() 'Сущность от сеанса работает. :) оставляя открытым, чтобы увидеть, есть ли у меня проницательные ответы ... – les2

ответ

10

ли вы действительно нужно использовать DTO? У вас не было бы этой проблемы, если бы вы проходили фактическую сущность вокруг - и вам не пришлось бы снова загружать объект, что не очень хорошо для производительности.

Но даже если у вас есть законная причина использовать DTO, я не совсем понимаю, почему вы пытаетесь обновить номер версии на своей только что перезагруженной объекте до сохранения. Рассмотрим различные сценарии возможны в рабочем процессе:

  1. Entity загружается на начальном этапе, имеет версию = V1
  2. Это передается DTO, который идет в UI, возвращается и готова быть сохранены.
  3. Объект загружается снова, имеет версию = V2

У Вас есть две возможности Сейчас:

  1. V1 == V2. Персиковый, вам не нужно ничего делать.
  2. V1 меньше, чем V2, то есть объект был обновлен кем-то еще, пока вы его редактировали. Нет причин пытаться установить версию на V1 и попытаться сохранить, потому что сбой не удастся. Вы можете либо сохранить его с помощью V2 (таким образом, переопределив чужие изменения), либо провалиться сейчас (без использования Hibernate).
+1

1. Перезагрузка может потребоваться, поскольку DTO может не содержать полностью все поля сущности, просто подмножество. 2. Как прокомментировал (и может также читать по ссылке внизу https://forum.hibernate.org/viewtopic.php?t=977889a), выселение может помочь здесь. – ron

 Смежные вопросы

  • Нет связанных вопросов^_^