2013-08-11 5 views
4

На работе мы разрабатываем приложение RESTful, в котором уровень данных будет обрабатываться Hibernate. Но мы не знаем, как обрабатывать обновления для сущностей.Оптимистическая блокировка в приложении RESTful

Мы планируем сделать следующее:

1) клиент запрашивает объект по идентификатору
2) Hibernate загружает сущность, запрашиваемые поля (всегда с версией) копируются в DTO, который конвертируется в JSON и отправляется клиенту
3) Клиент управляет некоторыми полями и отправляет объект (с номером версии) обратно на сервер.
4) Сервер получает JSON, который преобразован в DTO.
5) Соответствующий объект загружается из спящего режима, а реквизиты DTO копируются в объект.

=> Сущность всегда перезаписывается, даже если был установлен номер версии клиента. Означает ли это, что нам всегда нужно проверять номер версии клиента на номер версии загруженного экземпляра самостоятельно, а не на Hibernate?

В обычном приложении с сеансами отдельный экземпляр сохраняется в HttpSession. Всякий раз, когда клиент обновляет объект, экземпляр извлекается из HttpSession, и некоторые атрибуты обновляются. Всякий раз, когда Hibernate фиксирует обновление, будет выведено ObjectStaleException, если номер версии < - номер текущей версии.

Проблема в том, что у нас нет сессии Http, потому что мы пытаемся быть RESTful.

Есть ли общее решение для работы с оптимистичной блокировкой в ​​приложениях RESTful вместо того, чтобы самостоятельно проверять номера версий?

ответ

2

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

Вам не нужно ничего проверять самостоятельно. Hibernate делает чек для вас.

+1

Согласно спецификации Hibernate вы не можете изменить номер версии загруженного объекта. Поэтому я предполагаю, что мне придется создать новый экземпляр, который представляет измененный объект (со старым номером версии), а затем объединить его с загруженным объектом? Но merge будет игнорировать некоторые поля в случае частичного обновления ... Я все еще не уверен, как справиться с этим. – user2054927

+0

Это то, что делает слияние: он копирует состояние отдельного объекта в прикрепленное, включая версию. Если этого не произошло, оптимистичная блокировка будет полностью нарушена. Настройка версии явно или с помощью слияния будет иметь тот же эффект. Что означает документация, так это то, что вы не должны изменять номер версии, чтобы искусственно увеличить ее значение (потому что это могло бы вызвать исключение, если оно не должно, или не вызывать его, когда оно должно). –

+0

Могу ли я использовать saveOrUpdate() для этого? – user2054927