Java 刷新导致的延迟初始化错误

Java 刷新导致的延迟初始化错误,java,hibernate,spring,spring-mvc,velocity,Java,Hibernate,Spring,Spring Mvc,Velocity,当页面被多次请求时,如何防止引发LazyInitializationExceptions?如果我只是在我的webapp中的某个页面上按住Ctrl-R键,我就会在日志文件中始终收到此消息 我在servlet.xml文件中配置了以下拦截器: <mvc:interceptors> <bean class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor" /> <

当页面被多次请求时,如何防止引发LazyInitializationExceptions?如果我只是在我的webapp中的某个页面上按住Ctrl-R键,我就会在日志文件中始终收到此消息

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

<mvc:interceptors>
  <bean 
   class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor" />  
</mvc:interceptors>
注意:在拦截器上打开日志记录,我清楚地看到它正在被调用并打开/关闭事务:

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:53511[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:53511[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:53916[http-8080-5]DEBUG org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor IP134.167.141.34 CV#ef955014-cc9d-42fc P#75004-在OpenSessionInViewInterceptor中刷新单个Hibernate会话 2011-09-23 15:36:53916[http-8080-5]DEBUG org.springframework.web.servlet.DispatcherServlet IP134.167.141.34 CV#ef955014-cc9d-42fc P#75004-DispatcherServlet中名为“springmvc”的呈现视图[eqip.core.springmvc.extensions.velocity.VelocityToolsLayoutView:name'pages/myEqip';URL[pages/main.xhtml]] 2011-09-23 15:36:54213[http-8080-5]调试eqip.core.springmvc.extensions.velocity.VelocityToolsLayoutView IP134.167.141.34 CV#ef955014-cc9d-42fc P#75004-呈现屏幕内容模板[pages/main.xhtml] 2011-09-23 15:36:54384[http-8080-5]DEBUG org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor IP134.167.141.34 CV#ef955014-cc9d-42fc P#75004-关闭OpenSessionInViewInterceptor中的单个Hibernate会话

使用Spring 3.0.5、Hibernate 3.6.5、velocity 1.7

最终修复:正在向控制器声明中添加以下内容:

@Scope(BeanDefinition.SCOPE_PROTOTYPE) 

这使我们能够继续使用我们的拦截器,并确保在每次请求时获得预加载片段的新副本。

您确定实际调用了拦截器类吗?获取源代码,并对其进行调试,以查看执行是否真正到达源代码。确保您已经在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,它只需要配置为截取/*(或包含处理hibernate实体的控制器的所有URL的通用enoug URL)的servlet筛选器。

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

每次按Ctrl+R时,都会打开新的请求,并且在当前请求期间无法从以前的请求初始化代理对象,因此会引发
LazyInitializationException
exception


如果这不是你的情况,那么试着从这个方向挖掘

编写一个类,如:-

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>

OSIVF滤波器
您的.path.to.CustomHibernateSessionViewFilter
OSIVF滤波器
/*

OSIVF也有同样的问题。相信我,我很同情你。这是使用Hibernate的“好处”之一,Hibernate虽然很糟糕,但被另一个重量级框架(如Spring)包裹着,你可能会迷失在其中。我选择避免懒散的初始化。。。是使用“fetch join”从一开始就获取当前视图所需的所有数据。我的意思是,当一个选项足够时,为什么需要Hibernate发布一系列选项?哪个会话?Http会话还是Hibernate会话?我该如何验证?Http会话,不知何故,您的统一化代理被转发到下一个请求。我只是建议您查看应用程序逻辑或只是调试它。我会仔细检查一下。也许有什么东西在改变方向。这让我走上了正确的道路。对我来说,真正的问题在于使用拦截器,拦截器在处理请求之前为我加载数据,并设置这些字段值以在控制器代码中使用。我认为Spring为每个请求实例化了一个新对象,但是这些值由Spring缓存。因此,这些字段被导致我的问题的后续请求覆盖。
<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>