尽管使用了OpenSessionInView,但Spring中的LazyInitializationException

时间:2011-11-17 16:08:03

标签: java lazy-loading

我正在尝试学习Spring + Hibernate,并开始在Hibernate中使用Lazy加载。为实现这一目标,我需要使用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 :(得分:0)

该实体于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会话期间,您有懒惰的初始化异常。这是有道理的,因为当你在16:43:33提交第一个Hibernate会话时,附加到你加载的对象的Hibernate会话被关闭了。

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会话中。

您应该在最初从数据库加载时预先加载所需的数据(在初始加载对象时,在第一个会话关闭之前调用惰性getter)或者您应该只在字段中存储KEY / HTTP会话,并在后续请求中重新加载对象,以便在调用惰性getter时对象仍然具有与之关联的实时Hibernate会话。