Spring,Hibernate,Tiles,OpenSessionInViewFilter和LazyInitializationException

时间:2013-01-14 21:30:53

标签: spring hibernate lazy-loading tiles open-session-in-view

当我试图访问延迟加载的colection时,我在jsp上收到了LazyInitializationException:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.navigator.category.alias.CategoryAlias.products, no session or session was closed
    org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
    org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)
    org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:368)
    org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
    org.hibernate.collection.PersistentBag.iterator(PersistentBag.java:272)
    org.apache.taglibs.standard.tag.common.core.ForEachSupport.toForEachIterator(ForEachSupport.java:348)
    org.apache.taglibs.standard.tag.common.core.ForEachSupport.supportedTypeForEachIterator(ForEachSupport.java:224)
    org.apache.taglibs.standard.tag.common.core.ForEachSupport.prepare(ForEachSupport.java:155)
    javax.servlet.jsp.jstl.core.LoopTagSupport.doStartTag(LoopTagSupport.java:256)
    org.apache.jsp.WEB_002dINF.jsp.admin.categoryalias.all_005fcategory_005faliases_jsp._jspx_meth_c_005fforEach_005f1(all_005fcategory_005faliases_jsp.java:334)
    org.apache.jsp.WEB_002dINF.jsp.admin.categoryalias.all_005fcategory_005faliases_jsp._jspx_meth_c_005fforEach_005f0(all_005fcategory_005faliases_jsp.java:220)
    org.apache.jsp.WEB_002dINF.jsp.admin.categoryalias.all_005fcategory_005faliases_jsp._jspService(all_005fcategory_005faliases_jsp.java:111)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
    org.apache.jasper.servlet.JspServlet._serviceJspFile(JspServlet.java:390)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:954)
    org.apache.jasper.runtime.PageContextImpl.doInclude(PageContextImpl.java:684)
    org.apache.jasper.runtime.PageContextImpl.include(PageContextImpl.java:678)
    org.apache.tiles.jsp.context.JspTilesRequestContext.include(JspTilesRequestContext.java:103)
    org.apache.tiles.jsp.context.JspTilesRequestContext.dispatch(JspTilesRequestContext.java:96)
    org.apache.tiles.renderer.impl.TemplateAttributeRenderer.write(TemplateAttributeRenderer.java:44)
    org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
    org.apache.tiles.renderer.impl.ChainedDelegateAttributeRenderer.write(ChainedDelegateAttributeRenderer.java:76)
    org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
    org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:670)
    org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:336)
    org.apache.tiles.template.InsertAttributeModel.renderAttribute(InsertAttributeModel.java:210)
    org.apache.tiles.template.InsertAttributeModel.end(InsertAttributeModel.java:126)
    org.apache.tiles.jsp.taglib.InsertAttributeTag.doTag(InsertAttributeTag.java:311)
    org.apache.jsp.WEB_002dINF.jsp.admin.common.admin_002dlayout_jsp._jspx_meth_tiles_005finsertAttribute_005f2(admin_002dlayout_jsp.java:158)
    org.apache.jsp.WEB_002dINF.jsp.admin.common.admin_002dlayout_jsp._jspService(admin_002dlayout_jsp.java:88)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
    org.apache.jasper.servlet.JspServlet._serviceJspFile(JspServlet.java:390)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    org.apache.tiles.servlet.context.ServletTilesRequestContext.forward(ServletTilesRequestContext.java:241)
    org.apache.tiles.servlet.context.ServletTilesRequestContext.dispatch(ServletTilesRequestContext.java:222)
    org.apache.tiles.renderer.impl.TemplateAttributeRenderer.write(TemplateAttributeRenderer.java:44)
    org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
    org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:670)
    org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:690)
    org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:644)
    org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:627)
    org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:321)
    org.springframework.web.servlet.view.tiles2.TilesView.renderMergedOutputModel(TilesView.java:124)
    org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:262)
    org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1157)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:927)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:311)
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:101)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:91)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:182)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:173)
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
    com.navigator.filter.RedirectAndSearchEngineFilter.doFilterInternal(RedirectAndSearchEngineFilter.java:125)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
    org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) 

的web.xml:

    <filter>
        <filter-name>openSessionInViewFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>openSessionInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
...
    <servlet>
        <servlet-name>navigator</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/navigator-servlet.xml,
        /WEB-INF/security-context.xml
    </param-value>
</context-param>
<servlet-mapping>
    <servlet-name>navigator</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

导航-servlet.xml中:

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="configLocation">
        <value>classpath:hibernate.cfg.xml</value>
    </property>
    <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
    <property name="definitions" value="/WEB-INF/tiles.xml" />
    <property name="preparerFactoryClass" value="org.springframework.web.servlet.view.tiles2.SpringBeanPreparerFactory" />
</bean>

<bean id="viewResolver" class="org.springframework.web.servlet.view.tiles2.TilesViewResolver">
    <property name="requestContextAttribute" value="requestContext" />

    <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView" />
</bean>

另外我在navigator-servlet.xml的开头有一个指令(我不确定这一切都是必需的):

<tx:annotation-driven />
<mvc:annotation-driven />
<context:component-scan base-package="com.navigator" />
<context:annotation-config />
<mvc:resources mapping="/robots.txt" location="/robots.txt" />
<mvc:default-servlet-handler />

我知道LazyInitializationException是常见的问题,但是我花了很多时间在stackoverflow上的问题是我修复它的最后希望。

UPD1: Hibernate版本3.5.6,Spring - 3.1.0.RELEASE

2 个答案:

答案 0 :(得分:3)

这是与DispatcherServlet和contextConfigLocation之间的“冲突”相关的问题。 这个答案对我很有帮助:https://stackoverflow.com/a/12463483/1462024

为了解决我的问题,应该以下一种方式创建DispatcherServlet(应该在DispatcherServlet创建上添加 init-param部分):

<servlet>
    <servlet-name>navigator</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value></param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

答案 1 :(得分:1)

您的配置看起来没问题,从堆栈跟踪中可以看到OpenSessionInViewFilter正在正常运行。这让我们至少有两种可能性:

  1. 您已手动关闭会话(不太可能)
  2. CategoryAlias已分离(使用session.evict,或者因为您的实例是.clone()'ed)