问题
I am using Hibernate's lazy loading, and am getting sessionFactory missing exception, even after I have defined a filter in web.xml to use 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>
My servlet-context.xml has following session and transaction manager definitions:
<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" />
I still get the following exception:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'sessionFactory' is defined
I have tried defining a sessionFactoryBeanName attribute but results don't change. What am I doing wrong?
回答1:
You need to declare sessionFactory
in the root web application context (i. e. /WEB-INF/spring/root-context.xml
) to make it available to OpenSessionInViewFilter
.
回答2:
You have to put sesstionFactory Bean in your 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" />
回答3:
This is the code fragment inside the org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
class that looks up the 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);
}
You'll notice that it uses the WebApplicationContextUtils
class to load the session factory bean. The API (http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/context/support/WebApplicationContextUtils.html) for this class states :
Convenience methods for retrieving the root WebApplicationContext for a given ServletContext. This is useful for programmatically accessing a Spring application context from within custom web views or MVC actions.
Note that there are more convenient ways of accessing the root context for many web frameworks, either part of Spring or available as an external library. This helper class is just the most generic way to access the root context.
Thus you are required to declare the sessionFactory
in the root context if you wish to use the Spring provided OpenSessionInViewFilter
feature out of the box.
来源:https://stackoverflow.com/questions/8574552/spring-hibernate-lazy-loading-sessionfactory-and-opensessioninviewfilter