1

私はこれについてしばらく頭を悩ませてきました。一時的に放置していましたが、また取り上げる時が来ました。短いバージョンは次のとおりです。dispatcher-servlet.xml ファイルで OpenSessionInViewInterceptor を構成していますが、それでも恐ろしい LazyIntializationException が発生します。

では、詳細を。

次のように、dispatcher-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 および TransactionManager Bean は、通常の 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 を使用。

どんな助けでも大歓迎です。

ジェイソン

編集: 提案で、インターセプターではなくフィルターに切り替えようとしました。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>

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

1 に答える 1

0

jsp ビューでリレーションを展開するために OSIV を使用していると想定しています。この場合、インターセプターはビューがレンダリングされる前に処理を完了するため、この特定のケースでは jsp がレンダリングされる前にインターセプターが機能しない可能性があります。コンテナーによってレンダリングされた場合、休止状態のセッションは閉じられます。

より良いアプローチは、OSIV フィルターを使用することorg.springframework.orm.hibernate4.support.OpenSessionInViewFilterです。これは、jsp の遅延関係もサポートします。

更新:私が気づいたことの 1 つは、dispatcher-servlet.xml ファイルにインポートされた applicationContext.xml があることです。applicationContext.xml を dispatcher-servlet.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>

次に、dispatcher-servlet.xml の残りの部分を通常どおりロードします。これがこのルートによるものであると私が言っている理由はroot application context、シングルトンとして登録sessionFactoryされ、OSIV フィルターによって検出される休止状態に使用できるようにするためです。これも試してみて、どうなるか見てみませんか

于 2012-06-05T20:54:24.917 に答える