2012-06-05 62 views
1

我一直在这个问题上绞尽脑汁。我暂时把它放在一边,但现在是时候再次拿起它。简短的版本是这样的:虽然我的Dispatcher-servlet.xml文件中配置了OpenSessionInViewInterceptor,但我还是得到了可怕的LazyIntializationException。Spring MVC OpenSessionInViewInterceptor不能正常工作

现在,了解详情。

我有我的调度员servlet.xml中配置的OSIV拦截如下:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd 
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd" 
default-lazy-init="true"> 

<import resource="applicationContext.xml" /> 

<!-- This MUST be defined here or the DispatcherServlet will act a bit funky --> 
<context:component-scan base-package="org.me.app.web.controller" /> 

<!-- Configures the @Controller programming model --> 
<mvc:annotation-driven /> 


<!-- Convenient way to map URLs to JSPs w/o having a Controller --> 
<mvc:view-controller path="/index.html" view-name="index" /> 
<mvc:view-controller path="/UserAgreement.html" 
    view-name="UserAgreement" /> 

<mvc:interceptors> 
    <mvc:interceptor> 
     <mvc:mapping path="/**/*.html" /> 
     <bean 
      class="org.springframework.orm.hibernate4.support.OpenSessionInViewInterceptor"> 
      <property name="sessionFactory" ref="sessionFactory" /> 
     </bean> 
    </mvc:interceptor> 
</mvc:interceptors> 

的Hibernate的SessionFactory和事务管理豆在常规applicationContext.xml文件中定义:

<tx:annotation-driven /> 
<tx:advice id="transactionAdvice" transaction-manager="transactionManager"> 
    <tx:attributes> 
     <tx:method name="get*" read-only="true" propagation="REQUIRED"/> 
     <tx:method name="load*" read-only="true" propagation="REQUIRED"/> 
     <tx:method name="*" propagation="REQUIRED"/> 
    </tx:attributes> 
</tx:advice> 

<aop:config> 
    <aop:pointcut expression="execution(* *.manager.*Manager.*(..))" id="serviceOperations"/> 
    <aop:advisor advice-ref="transactionAdvice" pointcut-ref="serviceOperations" /> 
</aop:config> 

<bean id="sessionFactory" 
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop> 
      <prop key="hibername.format_sql">true</prop> 
      <prop key="hibernate.show_sql">false</prop> 
      <prop key="hibernate.cglib.use_reflection_optimizer">true</prop> 

     </props> 
    </property> 
    <property name="packagesToScan" value="org.me.app.model" /> 
</bean> 

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

使用Spring 3.1.1和Hibernate 4.1。

任何帮助,将不胜感激。

杰森

编辑:在建议下,我尝试切换到过滤器,而不是拦截。我注释掉派遣-servlet.xml中的整个部分,并添加以下到web.xml中(如图中以及其它过滤器和过滤器映射):

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>classpath:applicationContext.xml 
      classpath:security.xml 
    </param-value> 
</context-param> 

<filter> 
    <filter-name>osiv</filter-name> 
    <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class> 
</filter> 
<filter> 
    <filter-name>sitemesh</filter-name> 
    <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class> 
</filter> 
<filter> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter> 

<!-- This filter checks to see if the user has accepted terms --> 
<filter> 
    <filter-name>acceptTermsFilter</filter-name> 
    <filter-class>org.me.web.filter.terms.AcceptTermsFilter</filter-class> 
</filter> 


<filter-mapping> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
<filter-mapping> 
    <filter-name>osiv</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
<filter-mapping> 
    <filter-name>sitemesh</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
<filter-mapping> 

<filter-name>acceptTermsFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

<listener> 

    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 
+0

你的dispatcher-servlet.xml定义了两个类型为OpenSessionInViewInterceptor的bean实例。你需要两个吗?你可以离开顶层的实例,并在拦截器定义中引用它,或者删除顶层实例并离开嵌套层。我不知道这是不是意外行为的根源,但它可能有帮助。 –

+0

这是我尝试使它工作的剩余物。我拿出了额外的声明,但仍然没有奏效。我也编辑了这个例子来取出这个重复。 – Jason

回答

0

我假设你正在使用的OSIV扩大在jsp视图中取出一个关系 - 如果是这种情况,那么拦截器可能无法工作,因为拦截器在视图呈现之前完成了处理,在这个特定情况下,在容器呈现jsp之前,hibernate会关闭。

更好的方法可能是使用OSIV过滤器 - org.springframework.orm.hibernate4.support.OpenSessionInViewFilter这将支持jsp中的懒惰关系。

更新:有一两件事我注意到的是,你这是在您的调度员-servlet.xml文件导入的applicationContext.xml中,这将是最好不要导入调度-servlet.xml中applicationContext.xml中,而不是使用ContextLoaderListener加载它:

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 
<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value> 
</context-param> 

然后正常加载其余的调度程序-servlet.xml。我之所以这么说,是因为只有通过这条路径,root application context才会被注册为一个单身人士,并可用于OSIV过滤器检测到的休眠sessionFactory。你可以试试这个,看看它是怎么回事

+0

也没有运气。编辑原始帖子以显示我试图做的事情。 – Jason

+0

我注意到的一件事是你有一个通用的dispatcher-servlet.xml,它具有根环境和servlet特定的上下文,请你把它分离出来以便我更新。 –

+0

查看更新。当我提取web.xml的部分时,我忽略了这一点。我已经尝试了使用和不使用声明。 – Jason