2011-12-20 85 views
2

我使用Hibernate的延遲加載,和我越來越SessionFactory的缺失外,即使我在web.xml中定義了一個過濾器使用的OpenSessionInViewFilterspring,hibernate的延遲加載,SessionFactory,同時展示的OpenSessionInViewFilter

<?xml version="1.0" encoding="UTF-8"?> 
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 
<!-- The definition of the Root Spring Container shared by all Servlets and Filters --> 
<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/spring/root-context.xml</param-value> 
</context-param> 

<!-- Creates the Spring Container shared by all Servlets and Filters --> 
<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

<!-- Processes application requests --> 
<servlet> 
    <servlet-name>appServlet</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 
<servlet-mapping> 
    <servlet-name>appServlet</servlet-name> 
    <url-pattern>/</url-pattern> 
</servlet-mapping> 
<filter> 
    <filter-name>hibernateFilter</filter-name> 
    <filter-class> 
     org.springframework.orm.hibernate3.support.OpenSessionInViewFilter 
    </filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>hibernateFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
</web-app> 

我的servlet -context.xml有以下會話和事務管理的定義:

<beans:bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 
    <beans:property name="dataSource" ref="dataSource"/> 
    <beans:property name="hibernateProperties"> 
     <beans:props> 
      <beans:prop key="hibernate.dialect">${connection.dialect}</beans:prop> 
      <beans:prop key="hibernate.show_sql">true</beans:prop> 
     </beans:props> 
    </beans:property> 
    <beans:property name="annotatedClasses"> 
     <beans:list> 
      <beans:value>example.EntityA</beans:value> 
      <beans:value>example.EntityB</beans:value> 
     </beans:list> 
    </beans:property> 
</beans:bean> 

<beans:bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
    <beans:property name="sessionFactory" ref="sessionFactory"/> 
</beans:bean> 
<tx:annotation-driven transaction-manager="transactionManager" /> 

我仍然得到以下異常:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'sessionFactory' is defined 

我試着定義一個sessionFactoryBeanName屬性,但結果不會改變。我究竟做錯了什麼?

回答

3

您需要在根Web應用程序上下文(即/WEB-INF/spring/root-context.xml)中聲明sessionFactory以使其可用於OpenSessionInViewFilter

+0

This Works。有沒有辦法將所有過濾器設置都帶到servlet-context.xml中,因此不必在root-context.xml中定義sessionfactory?謝謝 – Loke 2011-12-20 11:51:31

+0

@Loke:編號'OpenSessionInViewFilter'在請求到達servlet之前被調用,因此過濾器不能訪問servlet特定的東西。 – axtavt 2011-12-20 11:54:42

0

你必須把sesstionFactory豆在servlet-context.xml的

<bean id="sessionFactory" 
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 
<property name="annotatedClasses"> 
    ..... 
</property> 
<property name="hibernateProperties"> 
    ...... 
</property> 
<property name="schemaUpdate" value="true" /> 

+0

我的會話 - 工廠已經**在** servlet-context.xml中。正如@axtavt建議的那樣,我可以通過在root-context.xml中定義sessionFactory來修復它。如果您能夠將sessionFactory保留在servlet-context.xml中,您是否會共享您的過濾器定義以及您定義它們的文件? – Loke 2011-12-20 11:56:55

0

這是org.springframework.orm.hibernate3.support.OpenSessionInViewFilter類中查找sessionFactory bean中的代碼片斷:

/** 
* Look up the SessionFactory that this filter should use. 
* <p>The default implementation looks for a bean with the specified name 
* in Spring's root application context. 
* @return the SessionFactory to use 
* @see #getSessionFactoryBeanName 
*/ 
protected SessionFactory lookupSessionFactory() { 
    if (logger.isDebugEnabled()) { 
     logger.debug("Using SessionFactory '" + getSessionFactoryBeanName() + "' for OpenSessionInViewFilter"); 
    } 
    WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); 
    return wac.getBean(getSessionFactoryBeanName(), SessionFactory.class); 
} 

您會注意到它使用WebApplicationContextUtils類來加載會話工廠bean。這個類狀態下的API(http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/context/support/WebApplicationContextUtils.html):

用於檢索根的WebApplicationContext對於一個給定的ServletContext便利方法。這對於從自定義Web視圖或MVC操作中以編程方式訪問Spring應用程序上下文很有用。

請注意,對於許多Web框架來說,訪問根環境 有更方便的方法,這些框架既可以是Spring的一部分,也可以作爲外部庫提供。這個輔助類只是 訪問根環境的最普遍的方式。

因此,你需要申報sessionFactory在根上下文如果你希望使用Spring提供OpenSessionInViewFilter功能開箱即用。