#hibernate #session #grails
#спящий режим #сеанс #grails
Вопрос:
Я знаю, что сохранение объекта в сеансе http — плохая идея, поскольку OSIV не может разрешить исключение LazyInitializationException, вызванное, когда я пытаюсь получить доступ к свойству типа коллекции этого объекта.
К сожалению, я сохранял некоторые объекты в сеансе http, например, CurrentUser :
Я сохраняю текущего пользователя в сеансе http следующим образом :
session.currentUser = loggedUser
У пользователя есть коллекция правил, например
session.currentUser.rules
Как и ожидалось, когда я пытаюсь получить доступ к коллекции правил в последующих запросах, я получаю исключение LazyInitializationException, поскольку session.CurrentUser теряет контекст сохранения.
Несмотря на то, что я перехожу к правильному подходу, который сохраняет идентификатор объекта в сеансе http, я должен найти решение для обеспечения того, чтобы доступ к свойству коллекции объектов, хранящихся в сеансе http, не вызывал исключения LazyInitializationException.
Я думаю о решении путем переопределения метода HttpSession:
HttpSession.metaClass.getProperty { name ->
if(name.equals("currentUser")){
def userId = delegate.getProperty(name).id
def userInstance = Utilisateur.get(userId)
println 'in metaclass currentUser ' userInstance.isAttached()
return userInstance
}else{
return delegate.getProperty(name)
}
}
вместо прямого возврата текущего пользователя я извлекаю вложенный объект из сеанса гибернации с помощью метода Get().
это решение кажется работающим, как вы думаете, это хорошая идея?
Ответ №1:
Самым простым решением было бы сделать rules
ассоциацию не ленивой
static mapping = {
rules lazy:false
}
который загрузит все правила для пользователя заранее при загрузке пользователя, поэтому нет необходимости возвращаться к сеансу гибернации позже.
Комментарии:
1. привет, Робертс, но я все еще хочу иметь режим отложенной выборки.
Ответ №2:
Вы должны убедиться, что ваш объект полностью инициализирован, прежде чем помещать его в сеанс. Лучший способ сделать это — обеспечить быстрый запрос. Так, например, если у вас User
есть rules
, вы бы сделали:
session.currentUser = User.findByLogin("blah", [fetch:[rules:"eager"])
Комментарии:
1. привет, Рошер, спасибо за ответ. но как вы думаете, мое решение будет работать нормально (переопределить getProperty() класса HttpSession)?
2. другой вопрос: является ли это нетерпеливым finder (User.findByLogin(«blah», [fetch:[rules:»нетерпеливый»])) эквивалентным Hibernate.initialize(usr.rules) ? Спасибо