Как реализовать параллельный GetOrCreate с JPA-сессией? - PullRequest
0 голосов
/ 19 января 2012

Мне нужно реализовать GetOrCreate (я его называю sureExists) сущности в веб-приложении, управляемом spring-jpa (hibernate).
У меня есть многоуровневое приложение (WS / Services / DAL / Datastore), и я хочу реализовать эту функциональность на уровне обслуживания (с пружинным управлением).
Основная идея:

  1. Find-объект
  2. Если найден, верните его.
  3. В противном случае сохраните сущность.
  4. Если все в порядке, верните его.
  5. Если произошло уникальное нарушение ограничения, попробуйте снова найти объект и вернуть его.

Проблема возникает из-за того, что после создания исключения сеанс гибернации должен быть закрыт и вновь открыт (из документации сеанса ), что делает шаг 5 недействительным, но я все еще хочу инкапсулировать эту логику в уровень обслуживания (и не иметь его в DAL или WS).

Мне бы очень хотелось услышать предложения о том, как это можно решить, у меня есть идея, но я хотел бы услышать некоторые комментарии, прежде чем публиковать их, чтобы не наклонять ответы на них.

Заранее спасибо

Обновление
Решение, которое я имею в виду, заключается в следующем:
Реорганизовать стадию 3 в сервис с областью действия пакета, который имеет единственный метод sureExists (с обобщениями), который принимает Dao этого типа и сущности и имеет распространение REQUIRES_NEW. Этот метод попытается сохранить, и, если произойдет сбой, он, конечно, выдаст исключение, которое будет перехвачено в исходном сервисе, и попытается сохранить его, если это исключение было сгенерировано.
Я хотел бы получить отзыв о том, как это можно реализовать в противном случае.
Если через пару дней никто не предложит иного, я опубликую это как ответ с примером кода и приму его.

1 Ответ

0 голосов
/ 19 января 2012

Чтобы найти сущность, вы можете использовать критерии api + отражение, чтобы заполнить все существенные свойства и выполнить поиск по образцу объекта. Для решения проблемы параллелизма рассмотрим пессимистическую блокировку. Когда вы выполняете загрузку, просто установите блокировку на этот объект и снимите эту блокировку после завершения всех транзакций. Не уверен, что это будет лучший выбор в отношении производительности, но вы никогда не должны получать исключения здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...