JPA: расширение контекста персистентности и удаление объектов

Кажется, существуют два шаблона для реализации бизнес-транзакций, которые охватывают несколько HTTP-запросов с помощью JPA:

  • entity-manager-per-request с отдельными объектами
  • расширенный контекст сохранения

Каковы преимущества этих шаблонов? Когда должно быть предпочтительным?

До сих пор я придумал:

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

Однако, не имея практического опыта работы с JPA, я уверен, что упустил что-то важное, поэтому этот вопрос.

В случае, если это имеет значение: мы намерены использовать JPA 2.0, поддерживаемый Hibernate 3.6.

Изменить. Наша технология просмотра - JSF 2.0 в контейнере EJB 3.1 с CDI и, возможно, Seam 3.

Ответ 1

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

  • EntityManager не являются потокобезопасными. Для каждого сеанса пользователя вам не нужен. Для каждого сеанса пользователя требуется один вкладке браузера.
  • Когда исключение выходит из EntityManager, считается недействительными и должны быть закрыты и заменены. Если вы планируете написать собственные расширения для каркаса для управления расширенным жизненным циклом, для осуществления этого необходимо быть пуленепробиваемым. Обычно в EM-per-request устанавливает исключение идет на какую-то страницу ошибок и то загрузка следующей страницы создает новый, так или иначе, всегда есть.
  • Равенство объектов не будет 100% в автоматическом режиме. Как указано выше, исключение может быть признано недействительным контекст объекта, загруженного ранее был связан, так что один из них теперь не будет равным. Создание этого предположение также предполагает высокий уровень мастерства и понимание того, как работает JPA и что ЭМ делает среди разработчики используют его. например., случайно используя слияние, когда он не нужно было возвращать новый объект, который не удовлетворяет == с его идентичными по полю предшественник. (обработка слияния, как SQL-обновление является чрезвычайно распространенным JPA noobie 'error' особенно потому что это просто не-большая часть время, чтобы оно скользило мимо.)
  • Если вы используете технологию просмотра который связывает POJO (например, SpringMVC) и вы планируете связывать веб-форму данные непосредственно на ваши сущности, вы быстро попадете в беду. Изменения подключенного объекта будут стать постоянными на следующем flush/commit, независимо от того, они были совершены в транзакции или не. Общая ошибка, веб-форма приходит и связывает некоторые недопустимые данные на сущность, проверка не выполняется и пытается вернуть экран, чтобы сообщить пользователь. Экран ошибки здания включает выполнение запроса. запрос триггеры flush/commit of persistence контекст. Изменения, связанные с приложением объект попадает в базу данных, надеясь вызвать исключение SQL, но возможно, просто сохраняются поврежденные данные.

(Проблема 4 может, конечно, также произойти с сеансом на запрос, если программирование неаккуратно, но вы не вынуждены активно работать, избегая его.)