刷新时的延迟初始化错误

时间:2011-09-23 19:21:29

标签: java hibernate spring spring-mvc velocity

如何在多次请求页面时阻止抛出LazyInitializationExceptions?如果我只是在我的webapp中的页面上按住Ctrl-R,我会一直在我的日志文件中收到此消息。

我在servlet.xml文件中配置了以下拦截器:

<mvc:interceptors>
  <bean 
   class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor" />  
</mvc:interceptors>

然而,我经常收到以下错误:

2011-09-23 15:14:28,854 [http-8080-23] ERROR org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/web-app].[springmvc]  - Servlet.service() for servlet springmvc threw exception
org.hibernate.LazyInitializationException: illegal access to loading collection
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:366)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:186)

注意:在拦截器上开启登录我清楚地看到它正在被调用并打开/关闭交易:

2011-09-23 15:36:53,229 [http-8080-5] DEBUG org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor IP134.167.141.34 CV#ef955014-cc9d-42fc P#75004 - Opening single Hibernate Session in OpenSessionInViewInterceptor
2011-09-23 15:36:53,229 [http-8080-5] WARN  eqip.core.springmvc.extensions.interceptors.AbstractAgencyDataInterceptor IP134.167.141.34 CV#ef955014-cc9d-42fc P#75004 - Pre handle: http://134.167.141.34:8080/web-app/main.xhtml Status: 200

2011-09-23 15:36:53,511 [http-8080-5] WARN org.hibernate.engine.StatefulPersistenceContext.ProxyWarnLog IP134.167.141.34 CV#ef955014-cc9d-42fc P#75004 - 缩小代理到班级core.model.entities.Subclass - 此操作中断== 2011-09-23 15:36:53,511 [http-8080-5] WARN org.hibernate.engine.StatefulPersistenceContext.ProxyWarnLog IP134.167.141.34 CV#ef955014-cc9d-42fc P#75004 - 将代理缩小到类core.model .entities.Subclass - 此操作中断== 2011-09-23 15:36:53,916 [http-8080-5] DEBUG org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor IP134.167.141.34 CV#ef955014-cc9d-42fc P#75004 - 刷新单个Hibernate会话的OpenSessionInViewInterceptor 2011-09-23 15:36:53,916 [http-8080-5] DEBUG org.springframework.web.servlet.DispatcherServlet IP134.167.141.34 CV#ef955014-cc9d-42fc P#75004 - 渲染视图[eqip.core。 springmvc.extensions.velocity.VelocityToolsLayoutView:name'swages / myEqip';名为“springmvc”的DispatcherServlet中的URL [pages / main.xhtml]] 2011-09-23 15:36:54,213 [http-8080-5] DEBUG eqip.core.springmvc.extensions.velocity.VelocityToolsLayoutView IP134.167.141.34 CV#ef955014-cc9d-42fc P#75004 - 渲染屏幕内容模板[页/ main.xhtml] 2011-09-23 15:36:54,384 [http-8080-5] DEBUG org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor IP134.167.141.34 CV#ef955014-cc9d-42fc P#75004 - 关闭单个Hibernate会话的OpenSessionInViewInterceptor

使用Spring 3.0.5,Hibernate 3.6.5,速度1.7

最终修复:将以下内容添加到控制器声明中:

@Scope(BeanDefinition.SCOPE_PROTOTYPE) 

这使我们能够继续使用我们的拦截器,并确保我们在每次请求时都获得了预装件的新副本。

3 个答案:

答案 0 :(得分:0)

您确定实际调用了拦截器类吗?获取源代码,并对其进行调试以查看执行是否实际到达它。确保在spring mvc配置中确实已将拦截器声明为拦截器:

 <bean id="urlMapping"class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> 
<property name="interceptors">
<list>
<ref bean="openSessionInViewInterceptor"/>
</list>
</property>

<property name="mappings">

</bean>

或者您可以使用更简单的OpenSessionInVIewFilter,它只需要配置为拦截/ *的servlet过滤器(或通用的enoug URL以包含处理hibernate实体的所有控制器的URL)。

答案 1 :(得分:0)

可能是你在会话中保存了一些hibernate对象,这些对象可能有未初始化的代理。

每次按Ctrl + R,新请求都会打开,并且无法在当前请求期间初始化上一个请求中的代理对象,并且结果LazyInitializationException异常会引发。

如果不是这种情况,那么试着朝这个方向挖掘它。

答案 2 :(得分:0)

写一个类,如: -

public class CustomHibernateSessionViewFilter extends   OpenSessionInViewFilter {

protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
    Session session = super.getSession(sessionFactory);
    session.setFlushMode(FlushMode.COMMIT);
    return session;
}

protected void closeSession(Session session, SessionFactory factory) {
    session.flush();
    super.closeSession(session, factory);
}

}

在web.xml中声明它如下: -

<filter>
    <filter-name>OSIVF Filter</filter-name>
    <filter-class>your.path.to.CustomHibernateSessionViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>OSIVF Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>