У меня есть приложение Grails (2.5.4), развернутое на производстве, которое получает большой объем трафика.Объект домена, хранящийся в сеансе, становится отсоединенным
При попытке доступа к полям из объектов домена, хранящихся в сеансе, мы получаем прерывистые исключения LazyInitializationException
.
Чтобы уточнить, как работает поток:
У нас есть фильтр (http://docs.grails.org/2.5.4/ref/Plug-ins/filters.html), который вызывается перед каждым действием контроллера. В этом фильтре мы храним объект домена в сессии (http://docs.grails.org/2.5.4/ref/Servlet%20API/session.html), как это:
session.account = Account.get(1)
В контроллере мы отыскиваем домен, как это:
def account = session.account
Затем мы проходим domain object к другой службе, которая вызывает другую службу, которая в конечном итоге пытается вызвать поле hasMany на объекте домена следующим образом:
account.transactions.name
выше бросает LazyInitializationException
с сообщением, похожим на это:
failed to lazily initialize a collection of role: com.example.app.Account.transactions, no session or session was closed
Так почему сеанс Hibernate закрывается до того, как запрос будет закончен, следовательно, исключением ленивых нагрузок.
Мы обнаружили, выполнив следующие действия в контроллере полностью устраняет ошибку от происходящий:
Account account = Account.findById(session.account.id)
Проблема заключается в том, я понятия не имею, почему и хотели бы, чтобы понять, почему это устраняет проблему, прежде чем слепо реализации это исправление в других частях приложения. Я не вижу причин, по которым объект должен быть отделен от сеанса Hibernate, поскольку этот поток происходит в одном запросе. Вдобавок к этому, это очень случайная проблема - это происходит, может быть, в 1% случаев, когда запрос сделан, если не меньше.
Чтобы уточнить, вопрос в том, Почему закрытие сеанса и почему объект отделен от сеанса Hibernate, когда все это происходит в пределах одного и того же запроса? Кроме того, почему это происходит очень редко и беспорядочно?
Вы пытались использовать 'account.attach()' перед попыткой доступа к 'account.transactions'? См. Http://docs.grails.org/latest/ref/Domain%20Classes/attach.html –
Эй. Я специально не пробовал это, но хотел бы, чтобы он работал так же хорошо, как и 'Account account = Account. findById (session.account.id) '. Мой вопрос заключается не в том, как повторно присоединить домен к сеансу, поскольку это легко, но почему его отделяют в первую очередь.Документация в указанной вами ссылке: «Если объект извлекается из сеанса и помещается в веб-область, например HttpSession, он будет« отсоединен »от сеанса Hibernate после закрытия сеанса и отбрасывается». Итак, почему сессия закрыта и отбрасывается, если запрос еще не закончен? – DeaIss
У Grails есть канал Slack, где гуру склонны болтаться. StackOverflow лучше подходит для вопросов «Как ...», поэтому я думаю, что у вас будет лучший успех в Slack или в списке рассылки Grails. –