2012-07-03 68 views
0

我在使用註釋和hibernate的Spring 3中遇到了一些問題。Spring 3 + LazyInitializationException + OpenSessionInViewFilter

我試圖在一個JSP中執行它,它將被包含在所有其他JSP中,它是一個頭文件。

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

我的用戶POJO有這樣

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

與通知的關係。如果我把從控制器或服務getNotifications正確標註的,我沒有問題,但是當我試圖執行代碼insede一個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> 

我的應用程序-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放在通知集合上,但它不是我想要的。我需要它是一個懶惰的關係。

在此先感謝!

+0

你對相應的服務有什麼@交易設置? – mmalmeida

回答

0

我認爲一個問題可能在於您正在使用OpenSessionInViewInterceptorOpenSessionInViewFilter。嘗試刪除其中的一個。

+0

對不起,攔截器是我測試的最後一個解決方案。刪除攔截器代碼仍然不工作。另外,刪除過濾器表單web.xml並留下攔截器代碼仍然失敗! – CAAY

+0

您可以提供有關$ {pageContext ['request']。userPrincipal.principal.notifications}的更多詳細信息。它是Spring Security認證嗎? –

+0

$ {pageContext ['request']。userPrincipal.principal}返回一個可以解析爲User(我自己的用戶)的Object。是的,這是春季安全認證。如果我在控制器中獲得主體,我可以將其轉換爲User並正確執行getNotifications()。問題是OpenSessionInViewFilter不會將會話擴展到我的JSP – CAAY

相關問題