2013-08-07 6 views
3

Я нашел странное состояние моей программы спящего режима. Вот мой кодHibernate - не удалось лениво инициализировать - сеанс или сеанс не закрыты

public Set<AnotherClass> getAnotherClassSetsFromSomeClass() { 
     Session session = HIbernateUtil.getSessionFactory().openSession(); 
     Transaction trans = session.beginTransaction(); 
     SomeClass sc = (SomeClass)session.get(SomeClass.class,"classId"); 
     trans.commit(); 
     session.close; 
     return sc.getAnotherClassSet(); 
    } 

Этот код выглядит отлично, если я запускаю его на консоли Java.

Если я использовал его один веб-приложение (JSF), я получил эту ошибку

не удалось инициализировать лениво - не сеанс или сеанс был закрыт

Он имеет один ко многим соотношение (One SomeClass имеет много других классов)

Сообщение об исключении, указывающее на возврат sc.getAnotherClassSet() в качестве нулевого указателя. Я уверен, что у меня есть данные в моей базе данных.

Ну, я нашел, что если я добавлю System.out.println(sc.getAnotherClassSet()) berfore return sc.getAnotherClassSet(), мой код работает нормально.

Любая идея, что произошло? Благодарю.

ответ

5

Возможно, ваша ассоциация @OneToMany сопоставлена ​​с fetchType="lazy" (может быть, по умолчанию). Это означает, что ассоциация в вашем случае AnotherClassSet не загружается при загрузке объекта SomeClass. Он загружается только при попытке получить к нему доступ, используя getAnotherClassSet().

Однако в вашем примере этот метод (getAnotherClassSet()) вызывается в статусе return после закрытия сессии.

Чтобы решить эту проблему, вы можете попытаться вызвать getAnotherClassSet() перед закрытием сессии, просто чтобы загрузить ассоциацию AnotherClassSet.

+0

Это ответ, но вместо этого вызывается getter или setter, лучше использовать атрибут класса с некоторой функцией, например getAnotherClassSet(). Size(), и он будет загружен в AnotherClassSet в SomeClass. Спасибо –

+0

Да, загрузка ассоциации 'AnotherClassSet' (из' SomeClass') - это то, что я пытался предложить в последнем абзаце моего ответа ;-) – Crferreira

1

Потому что вы используете lazy initialization (что является настройкой по умолчанию). В lazy initialization каждое поле коллекции выбирается только по запросу. Вы должны указать инициализацию как eager, чтобы ваш код работал. Eager initialization извлекает весь объект за один выбор.

+0

Вы можете объяснить, почему, если я добавлю System.out.println() перед возвратом, мой код работает? –

+0

После закрытия сессии, то есть 'session.close()', вы ничего не можете извлечь. – user2550754