【问题标题】:Spring 3 + LazyInitializationException + OpenSessionInViewFilterSpring 3 + LazyInitializationException + OpenSessionInViewFilter
【发布时间】:2012-07-03 10:37:38
【问题描述】:

我在使用 Spring 3 时遇到了一些问题,包括注释和休眠。

我试图在一个将包含在所有其他 JSP 中的 JSP 中执行此操作,它是一个标头。

${pageContext['request'].userPrincipal.principal.notifications}

我的用户 pojo 与这样的通知有关系

    @OneToMany(mappedBy="user", fetch = FetchType.LAZY)
    protected Collection<Notification> notifications;

如果我从正确注释的控制器或服务调用 getNotifications,我没有问题,但是当我尝试在 JSP 中执行代码时,我收到一个像这样的 LazyInitializationException:

org.hibernate.LazyInitializationException: failed to lazily initialize a 
     collection of role: org.prog.para.model.pojo.user.User.notifications, no session or 
     session was closed

我阅读了有关 OpenSessionInViewFilter 的信息,但我不知道为什么它不起作用。

我的 web.xml:

<filter>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    <init-param>
        <param-name>singleSession</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

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

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring/app-config.xml
        /WEB-INF/spring/security-config.xml
    </param-value>
</context-param>
<context-param>
    <param-name>defaultHtmlEscape</param-name>
    <param-value>true</param-value>
</context-param>

<servlet>
    <servlet-name>para-mvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/mvc-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>para-mvc</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/static/*</url-pattern>
</servlet-mapping>

我的 app-config.xml 文件是:

<context:component-scan base-package="org.prog.para">
    <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation" />
</context:component-scan>

<!-- Datasource -->
<import resource="ds-config.xml" />

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="org.prog.para.model.pojo" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
            <prop key="hibernate.default_schema">schema</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>

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

<tx:annotation-driven transaction-manager="hibernateTransactionManager"
    proxy-target-class="true" mode="proxy" />


<bean id="emailTemplateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
    <property name="prefix" value="/WEB-INF/views/templates/" />
    <property name="suffix" value=".html" />
    <property name="characterEncoding" value="UTF-8" />
    <property name="order" value="1" />
</bean>

<bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
    <property name="templateResolvers" ref="emailTemplateResolver" />
</bean>

<bean id="viewResolver" class="org.thymeleaf.spring3.view.ThymeleafViewResolver">
    <property name="templateEngine" ref="templateEngine" />
    <property name="characterEncoding" value="UTF-8" />
</bean>


<bean id="springApplicationContext" class="org.prog.para.config.SpringApplicationContext" />

有人知道我的失败在哪里吗?我不明白为什么在执行视图时我的会话关闭。

我可以将 FetchType.EAGER 放在通知集合上来解决它,但这不是我想要的。我需要它是一个懒惰的关系。

提前致谢!

【问题讨论】:

  • 你在对应的服务上有哪些@transaction设置?

标签: spring lazy-initialization


【解决方案1】:

我认为问题可能在于您同时使用OpenSessionInViewInterceptorOpenSessionInViewFilter。尝试删除其中一个。

【讨论】:

  • 抱歉,拦截器是我测试的最后一个解决方案。删除拦截器代码仍然不起作用。此外,删除过滤器表单 web.xml 并留下拦截器代码,仍然失败!
  • 您能否提供有关 ${pageContext['request'].userPrincipal.principal.notifications} 的更多详细信息。是 Spring Security 身份验证吗?
  • ${pageContext['request'].userPrincipal.principal} 返回一个可以解析给用户(我自己的用户)的对象。是的,这是弹簧安全认证。如果我在控制器中获取主体,我可以将其转换为 User 并正确执行 getNotifications()。问题是 OpenSessionInViewFilter 不会将会话扩展到我的 JSP
猜你喜欢
  • 2012-12-28
  • 1970-01-01
  • 1970-01-01
  • 2016-08-27
  • 1970-01-01
  • 2019-05-19
  • 2015-07-31
  • 2011-02-13
  • 1970-01-01
相关资源
最近更新 更多