Безопасная передача информации между Wicket и Hibernate в длительных разговорах - PullRequest
5 голосов
/ 27 мая 2010

Мы используем Wicket с Hibernate в фоновом режиме.

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

Чтобы избежать ошибок гибернации с отсоединенными объектами, мы теперь используем объекты-значения для передачи информации из сервисного слоя в Wicket.

Однако теперь мы получаем взрыв почти одинаковых объектов:

например.

  • Ответ (сопоставленная сущность сохранена в спящем режиме)
  • AnswerVO (неизменяемое значение объекта)
  • AnswerModel (изменяемый компонент в домене сеанса)
  • Модель калитки в обтекателе
  • и обычно это помещается в CompoundPropertyModel

Эта сантехника становится экспоненциально хуже, когда в объекты вовлечены коллекции других объектов.

Должен быть лучший способ организовать это.

Может кто-нибудь поделиться советами, как сделать это менее обременительным?

Может быть, сделать объекты-значения изменяемыми, чтобы мы могли убрать необходимость в компоненте поддержки Seaprate в Wicket?

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

Какие-нибудь другие хитрости или шаблоны?

Ответы [ 2 ]

3 голосов
/ 30 мая 2010

Используйте OpenSessionInViewFilter из Spring. Это поможет вам в создании спящего сеанса для каждого запроса. Однако он открывает только сеанс только для чтения. Чтобы выполнить любую операцию записи в ваши компоненты, я бы порекомендовал запустить транзакцию гибернации (для этого вы можете использовать TransactionTemplate из Spring). Существуют и другие способы выполнения операции записи, но я обнаружил, что это было проще всего для меня.

Теперь, чтобы очистить ваши бобы, вот что я склонен делать

  1. Имеются только сущностные бины
  2. Если вы хотите выйти без сохранения состояния, сохраняйте ключ бина сущности только в сеансе и перезагружайте бин при каждом отдельном запросе в диалоге с несколькими запросами
  3. Оставаться в состоянии состояния - маленький обманщик. Вам нужно отсоединить компонент управления данными до того, как компоненты сохранятся в вашем хранилище сеансов, и вам нужно будет повторно присоединить его обратно при выполнении последующих запросов. Естественно, если кто-то обновил сущность в фоновом режиме, вам придется иметь дело с ней в вашем приложении (т.е. сообщить пользователю, что «база данных была изменена извне и т. Д.»).

Я бы пошел с (2) выше, так как это довольно просто и будет работать в большинстве случаев. Не рекомендуется, когда ваши постоянные bean-компоненты модифицируются двумя отдельными сеансами, так как вы в конечном итоге переопределите предыдущие обновления.

Hibernate имеет некоторую документацию по работе с отсоединенными объектами .

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

обычным решением будет открытый сеанс в представлении «шаблон», см., Например, Осив с калиткой

У меня нет хорошего опыта работы с OSIV, поэтому я скорее советую установить границы транзакций ниже уровня GUI и решить печально известную исключительную ситуацию lazyInitializationException с умным запланированным поиском данных на бизнес-уровне или уровне обслуживания

...