Spring MVC OpenSessionInViewInterceptor不工作 [英] Spring MVC OpenSessionInViewInterceptor Not Working

查看:92
本文介绍了Spring MVC OpenSessionInViewInterceptor不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这一段时间里,我一直在绞尽脑汁。我暂时把它放在一边,但现在是时候再次拿起它。简短的版本是这样的:虽然我在Dispatcher-servlet.xml文件中配置了OpenSessionInViewInterceptor,但我仍然遇到了可怕的LazyIntializationException。



现在,详细了解



我在我的dispatcher-servlet.xml中配置了OSIV拦截器,如下所示:

 <?xml version =1.0encoding =UTF-8?> 
< beans xmlns =http://www.springframework.org/schema/beans
xmlns:xsi =http://www.w3.org/2001/XMLSchema-instancexmlns :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/上下文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/>

<! - 这个必须在这里定义,否则DispatcherServlet会显得有点时髦 - >
< context:component-scan base-package =org.me.app.web.controller/>

<! - 配置@Controller编程模型 - >
< mvc:annotation-driven />


<! - 将URL映射到JSP而不具有Controller的便捷方式 - >
< mvc:view-controller path =/ index.htmlview-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 =sessionFactoryref =sessionFactory/>
< / bean>
< / mvc:拦截器>
< / mvc:interceptors>

Hibernate SessionFactory和TransactionManager bean在常规applicationContext.xml文件中定义:

 < tx:annotation-driven /> 
< tx:advice id =transactionAdvicetransaction-manager =transactionManager>
< tx:attributes>
< tx:方法名称=get *只读=truepropagation =REQUIRED/>
< tx:方法名称=load *只读=truepropagation =REQUIRED/>
< tx:method name =*propagation =REQUIRED/>
< / tx:属性>
< / tx:advice>

< aop:config>
< / aop:config>

< bean id =sessionFactory
class =org.springframework.orm.hibernate4.LocalSessionFactoryBean>
< property name =dataSourceref =dataSource/>
< property name =hibernateProperties>
<道具>
< 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>

< /道具>
< / property>
< property name =packagesToScanvalue =org.me.app.model/>
< / bean>

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

使用Spring 3.1.1和Hibernate 4.1。



Jason

编辑:关于建议,我试图切换到过滤器而不是拦截器。我注释了dispatch-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>

<! - 此筛选器检查用户是否接受了条款 - >
< 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>


解决方案

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

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



更新:我注意到的一件事是您有一个applicationContext.xml被导入您的dispatcher-servlet.xml文件中,最好不要在dispatcher-servlet.xml中导入applicationContext.xml,而是使用ContextLoaderListener加载它:

 <听者GT; 
< 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>

,然后正常加载其余的dispatcher-servlet.xml。我说这个的原因只是通过这条路径,根应用程序上下文被注册为一个单例,并且可用于休眠 sessionFactory 被OSIV过滤器检测到。你可以请尝试这一点,看看它是如何去的


I have been racking my brain for awhile on this one. I had temporarily put it aside, but now it's time to pick it up again. The short version is this: although I have the OpenSessionInViewInterceptor configured in my dispatcher-servlet.xml file, I still get the dreaded LazyIntializationException.

Now, for the details.

I have the OSIV interceptor configured in my dispatcher-servlet.xml as follows:

<?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>

The Hibernate SessionFactory and TransactionManager beans are defined in the regular applicationContext.xml file:

<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>

Using Spring 3.1.1 and Hibernate 4.1.

Any help would be appreciated.

Jason

EDIT: On suggestion, I attempted to switch to the Filter rather than the Interceptor. I commented out the entire section of dispatch-servlet.xml and added the following to web.xml (with other filters and filter mappings shown as well):

<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>

解决方案

I am assuming that you are using the OSIV for expanding out a relation in the jsp view - if this is the case then an interceptor may not work, as interceptors complete their handling before the view is rendered, in this specific case before the jsp is rendered by the container the hibernate session would have been closed.

A better approach may be to use OSIV filter - org.springframework.orm.hibernate4.support.OpenSessionInViewFilter which will support the lazy relations in jsp also.

Update: One thing I noticed is that you have a applicationContext.xml which is imported in your dispatcher-servlet.xml file, it will be better to not import applicationContext.xml in dispatcher-servlet.xml, instead load it using a 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>

and then load up the rest of your dispatcher-servlet.xml normally. The reason I am saying this is only by this route does the root application context get registered as a singleton and available for the hibernate sessionFactory to be detected by the OSIV filter. Can you please try this also and see how it goes

这篇关于Spring MVC OpenSessionInViewInterceptor不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆