LazyInitializationException в Spring, несмотря на работающий OpenSessionInView - PullRequest
0 голосов
/ 17 ноября 2011

Я пытаюсь изучить Spring + Hibernate, и я начал использовать Lazy loading с Hibernate. Для этого мне нужно использовать OpenSessionInViewFilter.

Я думаю, что конфигурация в порядке, но я вставляю ее ниже.

Когда я пытаюсь лениво загрузить коллекцию @OneToMany, я получаю:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: lessonScheduler.model.User.applicationses, no session or session was closed

Но в журнале Hibernate вроде бы все в порядке. Сессия открывается, и первый уровень загружается без проблем (заканчивается в момент времени 16:43:33,122).

Но когда я пытаюсь лениво загрузить указанный объект, я получаю исключение, упомянутое выше.

Из журнала я вижу, что есть новый открытый сеанс, но затем он потерпел крах. Понятия не имею, почему ...

INFO: 16:43:32,439 DEBUG OpenSessionInViewFilter:239 – Using SessionFactory 'sessionFactory1' for OpenSessionInViewFilter
INFO: 16:43:32,439 DEBUG DefaultListableBeanFactory:242 – Returning cached instance of singleton bean 'sessionFactory1'
INFO: 16:43:32,439 DEBUG OpenSessionInViewFilter:181 – Opening single Hibernate Session in OpenSessionInViewFilter
INFO: 16:43:32,439 DEBUG SessionFactoryUtils:316 – Opening Hibernate Session
INFO: 16:43:32,439 DEBUG SessionImpl:220 – opened session at timestamp: 13215446124
INFO: 16:43:32,470 DEBUG DefaultListableBeanFactory:242 – Returning cached instance of singleton bean 'userController'
INFO: 16:43:32,548 DEBUG AbstractBatcher:366 – about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
INFO: 16:43:32,548 DEBUG ConnectionManager:421 – opening JDBC connection
INFO: 16:43:32,548 DEBUG DriverManagerDataSource:162 – Creating new JDBC DriverManager Connection to [jdbc:mysql://webdev.felk.cvut.cz:3306/koukavoj]
INFO: 16:43:32,845 DEBUG SQL:401 – select this_.id as id3_0_, this_.firstName as firstName3_0_, this_.lastName as lastName3_0_, this_.login as login3_0_, this_.mail as mail3_0_, this_.password as password3_0_, this_.tel as tel3_0_ from koukavoj.user this_ where this_.id=? limit ?
INFO: Hibernate: select this_.id as id3_0_, this_.firstName as firstName3_0_, this_.lastName as lastName3_0_, this_.login as login3_0_, this_.mail as mail3_0_, this_.password as password3_0_, this_.tel as tel3_0_ from koukavoj.user this_ where this_.id=? limit ?
INFO: 16:43:32,987 DEBUG AbstractBatcher:382 – about to open ResultSet (open ResultSets: 0, globally: 0)
INFO: 16:43:33,002 DEBUG Loader:1173 – result row: EntityKey[lessonScheduler.model.User#1]
INFO: 16:43:33,025 DEBUG AbstractBatcher:389 – about to close ResultSet (open ResultSets: 1, globally: 1)
INFO: 16:43:33,025 DEBUG AbstractBatcher:374 – about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
INFO: 16:43:33,040 DEBUG TwoPhaseLoad:107 – resolving associations for [lessonScheduler.model.User#1]
INFO: 16:43:33,078 DEBUG TwoPhaseLoad:206 – done materializing entity [lessonScheduler.model.User#1]
INFO: 16:43:33,079 DEBUG StatefulPersistenceContext:790 – initializing non-lazy collections
INFO: 16:43:33,080 DEBUG ConnectionManager:302 – transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
INFO: 16:43:33,115 DEBUG OpenSessionInViewFilter:207 – Closing single Hibernate Session in OpenSessionInViewFilter
INFO: 16:43:33,116 DEBUG SessionFactoryUtils:789 – Closing Hibernate Session
INFO: 16:43:33,117 DEBUG ConnectionManager:441 – releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
INFO: 16:43:33,122 DEBUG ConnectionManager:302 – transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
INFO: 16:44:42,721 DEBUG OpenSessionInViewFilter:239 – Using SessionFactory 'sessionFactory1' for OpenSessionInViewFilter
INFO: 16:44:42,722 DEBUG DefaultListableBeanFactory:242 – Returning cached instance of singleton bean 'sessionFactory1'
INFO: 16:44:42,723 DEBUG OpenSessionInViewFilter:181 – Opening single Hibernate Session in OpenSessionInViewFilter
INFO: 16:44:42,723 DEBUG SessionFactoryUtils:316 – Opening Hibernate Session
INFO: 16:44:42,724 DEBUG SessionImpl:220 – opened session at timestamp: 13215446827
INFO: 16:44:42,735 DEBUG DefaultListableBeanFactory:242 – Returning cached instance of singleton bean 'userController'
INFO: 16:44:42,737 DEBUG DefaultListableBeanFactory:242 – Returning cached instance of singleton bean 'userController'
INFO: 16:44:42,738 DEBUG DefaultListableBeanFactory:242 – Returning cached instance of singleton bean 'userController'
INFO: 16:44:42,744 ERROR LazyInitializationException:19 – failed to lazily initialize a collection of role: lessonScheduler.model.User.applicationses, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: lessonScheduler.model.User.applicationses, no session or session was closed

Web.xml выглядит так:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <context-param>
        <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
        <param-value>.xhtml</param-value>
    </context-param>
    <listener>
        <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
    </listener>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

  <filter>
    <filter-name>hibernateFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    <init-param>
      <param-name>sessionFactoryBeanName</param-name>
      <param-value>sessionFactory1</param-value>
    </init-param>
    <init-param>
      <param-name>singleSession</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>

    <filter-mapping>
        <filter-name>hibernateFilter</filter-name>
        <url-pattern>*.xhtml</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

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

Заранее спасибо

1 Ответ

0 голосов
/ 17 ноября 2011

Объект был загружен в 16: 43: 32

INFO: 16:43:32,845 DEBUG SQL:401 – select this_.id as id3_0_, this_.firstName as firstName3_0_, this_.lastName as lastName3_0_, this_.login as login3_0_, this_.mail as mail3_0_, this_.password as password3_0_, this_.tel as tel3_0_ from koukavoj.user this_ where this_.id=? limit ?

Сессия, в которой он был загружен, была закрыта в 16: 43: 33:

INFO: 16:43:33,115 DEBUG OpenSessionInViewFilter:207 – Closing single Hibernate Session {...}

Очередная сессия была открыта в 16: 44: 42:

INFO: 16:44:42,723 DEBUG SessionFactoryUtils:316 – Opening Hibernate Session

Именно во время этого второго сеанса Hibernate у вас возникло исключение отложенной инициализации. Это имеет смысл, поскольку сеанс Hibernate, прикрепленный к загруженному объекту, был закрыт, когда первый сеанс Hibernate был зафиксирован в 16: 43: 33.

INFO: 16:44:42,744 ERROR LazyInitializationException:19 – failed to lazily initialize a collection of role: lessonScheduler.model.User.applicationses, no session or session was closed

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

Вам следует либо предварительно загрузить данные, которые вам нужны, когда вы изначально загружаете их из базы данных (вызывая ленивый метод получения, когда объект изначально загружен, до того, как первый сеанс закрыт) ИЛИ вам следует хранить только КЛЮЧ в поле / HTTP-сеанс и перезагрузите объект в последующем запросе, чтобы при вызове ленивого получателя объект все еще имел активный сеанс Hibernate, связанный с ним.

...