объединение / повторное присоединение IN JPA / Hibernate без обновления БД - PullRequest
4 голосов
/ 10 мая 2010

Работа с JPA / Hibernate в веб-среде OSIV сводит меня с ума;)

Следующий сценарий: у меня есть объект A, который загружается через JPA и содержит коллекцию объектов B. Эти B-объекты имеют обязательное поле.

Когда пользователь добавляет новый B в A, нажимая на ссылку в веб-приложении, это обязательное поле не устанавливается (поскольку разумного значения по умолчанию нет).

При следующем http-запросе фильтр OSIV пытается объединить объект A, но это не удается, поскольку Hibernate сообщает, что для нового B не установлено обязательное поле.

javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value

Читая спецификацию JPA, я не вижу признаков того, что эти проверки требуются в фазе слияния (у меня нет активной транзакции)

Я не могу хранить коллекцию B за пределами A и добавлять их в A только тогда, когда пользователь нажимает «save» (aka entitymanager.persist ()), поскольку место, где находится кнопка сохранения, не знает о B , только около А.

Также A и B - только примеры, у меня везде одинаковые вещи.

Есть идеи? Другие реализации JPA ведут себя здесь так же?

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

1 Ответ

2 голосов
/ 11 мая 2010

Я много читал и тестировал. Проблема возникла из-за моего неправильного понимания JPA / Hibernate. merge () всегда выполняет поиск в БД, а также планирует обновление для объекта. Я не нашел упоминаний об этом в спецификации JPA, но в книге «Java Persistence with Hibernate» об этом упоминается.

Если смотреть через API EntityManager (и Session в качестве запасного), то выглядит так, как будто нет средств просто назначить сущность текущему постоянному контексту БЕЗ планирования расписания обновления. В конце концов, я хочу перемещаться по графу объектов, изменяя свойства по мере необходимости и запускать обновление (с проверкой версии при необходимости) позже. Я думаю, что каждый Webapp, использующий ORM, должен это делать?

Базовый рабочий процесс, который я ищу:

  1. загрузить объект из БД (или создать новый)
  2. позволяют сущности (и все ее ассоциации становятся отсоединенными (когда EntitManager закрывается в конце HTTP-запроса)
  3. когда приходит следующий HTTP-запрос, снова поработайте с этими объектами, перемещаясь по дереву, не опасаясь LazyInitExceptions
  4. вызов метода, который сохраняет все изменения, сделанные в течение 1-3)

С фильтром OSIV из весны в сочетании с реализацией IModel из калитки я подумал, что я заархивировал это.

Я в основном вижу 2 возможных выхода из этого:

a) загрузить сущность и все ассоциации, необходимые при входе на определенную страницу (вариант использования), позволяя им отсоединиться, добавляя / изменяя их по мере необходимости в течение нескольких запросов http. Затем присоедините их, когда пользователь инициирует сохранение (валидаторы обеспечат правильное состояние), и отправьте их в базу данных.

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

Как другие люди работают с JPA в веб-среде? Любые другие варианты для меня?

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