проблема с отложенной инициализацией гибернации:Исключение LazyInitializationException:не удалось лениво инициализировать коллекцию ролей
-
13-09-2019 - |
Вопрос
Я хочу управлять транзакцией на моем уровне сохраняемости, Но когда я пытаюсь лениво получить результаты, я получаю эту ошибку:
org.спящий режим.Исключение LazyInitializationException:не удалось лениво инициализировать коллекцию ролей
Могу ли я использовать LockMode или любой другой способ решить эту проблему?Может ли a найти объект по его идентификатору без какой-либо транзакции?
Решение
Ваша проблема в том, что сеанс гибернации уже закрыт, когда вы пытаетесь получить доступ к содержимому.Режим гибернации не может загрузить содержимое без сеанса.Обычно есть два способа смягчить эту проблему:
Не закрывайте сеанс, пока не закончите работу со страницей.Этот шаблон называется "сеанс в режиме просмотра" и может, например, быть реализован с помощью фильтра сервлета.
Инициализируйте все содержимое, которое вам понадобится, перед закрытием сеанса.Если вы хотите инициализировать весь объект целиком, вы можете использовать Hibernate.initialize(объект).
Редактировать:Вы не можете ничего делать вне транзакции в режиме Гибернации.
Другие советы
Вы также можете ознакомиться с официальным решением от hibernate по адресу http://www.hibernate.org/43.html
Обычно проблема заключается в том, что один из атрибутов объекта загружается лениво.Единственное, что вы можете сделать, это предварительно загрузить его в свой запрос:
из продажи распродажа где распродажа.дата > : Дата начала осталось присоединиться к распродаже.товар
Это приведет к предварительной выборке объекта sale.product.
на этом сайте есть более подробная информация: http://www.javalobby.org/articles/hibernate-query-101/.
-Дэйв
Существует много способов предварительной выборки свойств, поэтому они доступны после закрытия сеанса:
- Просто вызовите соответствующего добытчика.После того, как поле загружено в bean, оно находится там после закрытия сеанса.
- Используйте соответствующий атрибут в дескрипторе компонента в JPA, который вы бы использовали
@OneToMany(fetch = FetchType.EAGER)
, но существуют аналогичные способы перехода в спящий режим для этого. - Вы можете инициализировать поле в запросе HQL (я не уверен, работает ли это в HQL, но я думаю, что работает), найдите
FETCH INTO
ключевое слово.
Или просто используйте другой ORM ...как Ebean ORM, где просто работает отложенная загрузка :)