Spring MVC3.2.2 + Hibernate4 + @Autowire SessionFactory sessionFactory给出nullpointer异常

时间:2013-06-16 19:28:09

标签: hibernate spring-mvc maven-3

我正在使用GenricHibernateDAO,它会自动发送一个sessionfactory,当我通过控制器调用save(user)方法时,它会一直设置为null,它会给我一个空指针异常。

package com.hdo.dao;
    public class GenericHibernateDAO<T> implements GenericDAO<T> {

        @Autowired
        private SessionFactory sessionFactory;

        public void setSessionFactory(SessionFactory sessionFactory) {
            this.sessionFactory = sessionFactory;
        }


        @Override
        @Transactional
        public void save(T t) {
            // TODO Auto-generated method stub
            sessionFactory.getCurrentSession().save(t);
        }
    }

UserDAO:

@Repository
public class UserDAO extends GenericHibernateDAO<User> {

    public UserDAO() {
        super(User.class);
    }
    public void createUser(User user) {

        save(user);
    }
}

控制器:

@Controller
public class BasicController {

    Logger _LOG = Logger.getLogger(BasicController.class);

    @RequestMapping("/")
    public ModelAndView home() {
        return new ModelAndView("index");
    }

    @RequestMapping("/userHome")
    public ModelAndView goHome(@ModelAttribute("user") User user, Map<String, Object> map, HttpServletRequest request) {
        if (null != user) {
            //userForm.get
            int noOfBreeds = Integer.parseInt(user.getNoOfBreeds());
            for (int i = 0; i < noOfBreeds; i++) {
                Pet pet = new Pet();
                String dogName = request.getParameter("dogName"+i);
                String breed = request.getParameter("breed"+i);
                pet.setPetName(dogName);
                pet.setPetType(breed);

                user.addPet(pet);
            }

            new UserDAO().save(user);
        }

        return new ModelAndView("userHome");
    }
}

pom.xml(properties)

spring.version : 3.2.2.RELEASE
jdk.version : 1.7
hibernate.version : 4.2.0.Final
mysql.connector.version : 5.1.21 
tomcat.version : 7.0.33
cglib : 2.2.2
jstl : 1.2
commons-dbcp : 1.4
javax.servlet : 3.0.1

弹簧servlet.xml中

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">        

    <context:component-scan base-package="com.hdo" />
    <mvc:annotation-driven />

    <bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="classpath:i18n/messages" />
        <property name="defaultEncoding" value="UTF-8" />
    </bean>

    <bean id="localeChangeInterceptor"
        class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
        <property name="paramName" value="lang" />
    </bean>

    <bean id="localeResolver"
        class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
        <property name="defaultLocale" value="en" />
    </bean>

    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>

</beans>

application-context.xml

<?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:tx="http://www.springframework.org/schema/tx"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

    <context:annotation-config></context:annotation-config>
<context:property-placeholder location="classpath:jdbc.properties"/>

<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName">
        <value>${jdbc.driverClassName}</value>
    </property>
    <property name="url">
        <value>${jdbc.databaseurl}</value>
    </property>
    <property name="username">
        <value>${jdbc.username}</value>
    </property>
    <property name="password">
        <value>${jdbc.password}</value>
    </property>
</bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="com.hdo.model" /> <!-- assuming that is the package with your hibernate entities -->
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${jdbc.dialect}</prop>
                <prop key="hibernate.show_sql">${jdbc.showSql}</prop>
            </props>
        </property>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>

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

</beans>

Web.xml:

    <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/application-context.xml, /WEB-INF/spring-servlet.xml</param-value>
 </context-param>

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

<servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value></param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

日志在这里:

    00:06:06,297 DEBUG DefaultIdentifierGeneratorFactory:93 - Registering IdentifierGenerator strategy [enhanced-table] -> [org.hibernate.id.enhanced.TableGenerator]
    00:06:06,304  INFO Configuration:1969 - HHH000044: Configuring from URL: file:/home/hanu/tools/tomcat7maven_hpo/webapps/hpo/WEB-INF/classes/hibernate.cfg.xml
    00:06:06,357 DEBUG DTDEntityResolver:68 - Trying to resolve system-id [http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd]
    00:06:06,365 DEBUG DTDEntityResolver:70 - Recognized hibernate namespace; attempting to resolve on classpath under org/hibernate/
    00:06:06,367 DEBUG DTDEntityResolver:107 - Located [http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd] in classpath
    00:06:06,400 DEBUG Configuration:2134 - Session-factory config [null] named class [com.hdo.model.User] for mapping
    00:06:06,417  INFO Configuration:2074 - HHH000041: Configured SessionFactory: null


    00:06:06,715 DEBUG SimpleValueBinder:331 - building SimpleValue for userName
    00:06:06,716 DEBUG PropertyBinder:260 - Building property userName
    00:06:06,719 DEBUG SimpleValueBinder:369 - Setting SimpleValue typeName for id
    00:06:06,720 DEBUG SimpleValueBinder:369 - Setting SimpleValue typeName for confirmPassword
    00:06:06,720 DEBUG SimpleValueBinder:369 - Setting SimpleValue typeName for country
    00:06:06,720 DEBUG SimpleValueBinder:369 - Setting SimpleValue typeName for email
    00:06:06,721 DEBUG SimpleValueBinder:369 - Setting SimpleValue typeName for location
    00:06:06,721 DEBUG SimpleValueBinder:369 - Setting SimpleValue typeName for noOfBreeds
    00:06:06,722 DEBUG SimpleValueBinder:369 - Setting SimpleValue typeName for password
    00:06:06,722 DEBUG SimpleValueBinder:369 - Setting SimpleValue typeName for postCode
    00:06:06,723 DEBUG SimpleValueBinder:369 - Setting SimpleValue typeName for state
    00:06:06,723 DEBUG SimpleValueBinder:369 - Setting SimpleValue typeName for userName
    00:06:06,725 DEBUG Configuration:1406 - Processing fk mappings (*ToOne and JoinedSubclass)
    00:06:06,728 DEBUG Configuration:1585 - Processing extends queue
    00:06:06,729 DEBUG Configuration:1643 - Processing extends queue
    00:06:06,729 DEBUG Configuration:1588 - Processing collection mappings
    00:06:06,730 DEBUG Configuration:1598 - Processing native query and ResultSetMapping mappings
    00:06:06,730 DEBUG Configuration:1606 - Processing association property references
    00:06:06,730 DEBUG Configuration:1628 - Creating tables' unique integer identifiers
    00:06:06,731 DEBUG Configuration:1629 - Processing foreign key constraints
    00:06:07,128 DEBUG JdbcServicesImpl:121 - Database ->
       name : MySQL
    version : 5.5.29-0ubuntu0.12.10.1
      major : 5
      minor : 5
    00:06:07,129 DEBUG JdbcServicesImpl:127 - Driver ->
       name : MySQL-AB JDBC Driver
    version : mysql-connector-java-5.1.21 ( Revision: ${bzr.revision-id} )
      major : 5
      minor : 1
    00:06:07,130 DEBUG JdbcServicesImpl:133 - JDBC version : 4.0
    00:06:07,169  INFO Dialect:128 - HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
    00:06:07,216 DEBUG SettingsFactory:114 - Automatic flush during beforeCompletion(): disabled
    00:06:07,217 DEBUG SettingsFactory:120 - Automatic session close at end of transaction: disabled
    00:06:07,217 DEBUG SettingsFactory:131 - JDBC batch size: 15
    00:06:07,218 DEBUG SettingsFactory:137 - JDBC batch updates for versioned data: disabled
    00:06:07,218 DEBUG SettingsFactory:147 - Scrollable result sets: enabled
    00:06:07,219 DEBUG SettingsFactory:153 - Wrap result sets: disabled
    00:06:07,219 DEBUG SettingsFactory:159 - JDBC3 getGeneratedKeys(): enabled
    00:06:07,219 DEBUG SettingsFactory:171 - multi-tenancy strategy : NONE
    00:06:07,220 DEBUG SettingsFactory:177 - Connection release mode: auto
    00:06:07,220  INFO TransactionFactoryInitiator:68 - HHH000399: Using default transaction strategy (direct JDBC transactions)
    00:06:07,226 DEBUG SettingsFactory:199 - Using BatchFetchStyle : LEGACY
    00:06:07,227 DEBUG SettingsFactory:218 - Maximum outer join fetch depth: 2
    00:06:07,227 DEBUG SettingsFactory:224 - Default batch fetch size: 1
    00:06:07,228 DEBUG SettingsFactory:230 - Generate SQL with comments: disabled
    00:06:07,228 DEBUG SettingsFactory:236 - Order SQL updates by primary key: disabled
    00:06:07,228 DEBUG SettingsFactory:242 - Order SQL inserts for batching: disabled
    00:06:07,229 DEBUG SettingsFactory:250 - Default null ordering: none
    00:06:07,230 DEBUG SettingsFactory:541 - Query translator: org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory
    00:06:07,234  INFO ASTQueryTranslatorFactory:48 - HHH000397: Using ASTQueryTranslatorFactory
    00:06:07,235 DEBUG SettingsFactory:260 - Query language substitutions: {}
    00:06:07,235 DEBUG SettingsFactory:266 - JPA-QL strict compliance: disabled
    00:06:07,236 DEBUG SettingsFactory:274 - Second-level cache: enabled
    00:06:07,236 DEBUG SettingsFactory:280 - Query cache: disabled


    00:06:07,842 DEBUG BeanNameUrlHandlerMapping:86 - Rejected bean name 'org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping': no URL paths identified
    00:06:07,843 DEBUG BeanNameUrlHandlerMapping:86 - Rejected bean name 'org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter': no URL paths identified
    00:06:07,843 DEBUG BeanNameUrlHandlerMapping:86 - Rejected bean name 'org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter': no URL paths identified
    00:06:07,843 DEBUG BeanNameUrlHandlerMapping:86 - Rejected bean name 'org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#0': no URL paths identified
    00:06:07,843 DEBUG BeanNameUrlHandlerMapping:86 - Rejected bean name 'messageSource': no URL paths identified
    00:06:07,843 DEBUG BeanNameUrlHandlerMapping:86 - Rejected bean name 'localeChangeInterceptor': no URL paths identified
    00:06:07,844 DEBUG BeanNameUrlHandlerMapping:86 - Rejected bean name 'localeResolver': no URL paths identified
    00:06:07,844 DEBUG BeanNameUrlHandlerMapping:86 - Rejected bean name 'org.springframework.web.servlet.view.InternalResourceViewResolver#0': no URL paths identified
    00:06:07,844 DEBUG BeanNameUrlHandlerMapping:86 - Rejected bean name 'dataSource': no URL paths identified
    00:06:07,844 DEBUG BeanNameUrlHandlerMapping:86 - Rejected bean name 'sessionFactory': no URL paths identified
    00:06:07,845 DEBUG BeanNameUrlHandlerMapping:86 - Rejected bean name 'genericHibernateDAO': no URL paths identified
    00:06:07,845 DEBUG BeanNameUrlHandlerMapping:86 - Rejected bean name 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor': no URL paths identified
    00:06:07,845 DEBUG BeanNameUrlHandlerMapping:86 - Rejected bean name 'environment': no URL paths identified
    00:06:07,845 DEBUG BeanNameUrlHandlerMapping:86 - Rejected bean name 'systemProperties': no URL paths identified
    00:06:07,846 DEBUG BeanNameUrlHandlerMapping:86 - Rejected bean name 'systemEnvironment': no URL paths identified
    00:06:07,846 DEBUG BeanNameUrlHandlerMapping:86 - Rejected bean name 'servletConfig': no URL paths identified
    00:06:07,846 DEBUG BeanNameUrlHandlerMapping:86 - Rejected bean name 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry': no URL 

    00:06:07,886 DEBUG DefaultListableBeanFactory:215 - Creating shared instance of singleton bean 'org.springframework.web.servlet.view.InternalResourceViewResolver#0'
    00:06:07,886 DEBUG DefaultListableBeanFactory:435 - Creating instance of bean 'org.springframework.web.servlet.view.InternalResourceViewResolver#0'
    00:06:07,902 DEBUG DefaultListableBeanFactory:509 - Eagerly caching bean 'org.springframework.web.servlet.view.InternalResourceViewResolver#0' to allow for resolving potential circular references
    00:06:07,926 DEBUG DefaultListableBeanFactory:463 - Finished creating instance of bean 'org.springframework.web.servlet.view.InternalResourceViewResolver#0'
    00:06:07,927 DEBUG DefaultListableBeanFactory:246 - Returning cached instance of singleton bean 'dataSource'
    00:06:07,927 DEBUG DefaultListableBeanFactory:246 - Returning cached instance of singleton bean 'sessionFactory'
    00:06:07,927 DEBUG DefaultListableBeanFactory:215 - Creating shared instance of singleton bean 'genericHibernateDAO'
    00:06:07,928 DEBUG DefaultListableBeanFactory:435 - Creating instance of bean 'genericHibernateDAO'
    00:06:07,930 DEBUG InjectionMetadata:71 - Registered injected element on class [com.hdo.dao.GenericHibernateDAO]: AutowiredFieldElement for private org.hibernate.SessionFactory com.hdo.dao.GenericHibernateDAO.sessionFactory
    00:06:07,931 DEBUG DefaultListableBeanFactory:509 - Eagerly caching bean 'genericHibernateDAO' to allow for resolving potential circular references
    00:06:07,935 DEBUG InjectionMetadata:85 - Processing injected method of bean 'genericHibernateDAO': AutowiredFieldElement for private org.hibernate.SessionFactory com.hdo.dao.GenericHibernateDAO.sessionFactory
    00:06:07,935 DEBUG DefaultListableBeanFactory:246 - Returning cached instance of singleton bean 'sessionFactory'
    00:06:07,936 DEBUG AutowiredAnnotationBeanPostProcessor:433 - Autowiring by type from bean name 'genericHibernateDAO' to bean named 'sessionFactory'
    00:06:07,936 DEBUG DefaultListableBeanFactory:246 - Returning cached instance of singleton bean 'sessionFactory'
    00:06:07,937 DEBUG DefaultListableBeanFactory:463 - Finished creating instance of bean 'genericHibernateDAO'
    00:06:07,937 DEBUG DefaultListableBeanFactory:246 - Returning cached instance of singleton bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor'
    00:06:07,937 DEBUG XmlWebApplicationContext:858 - Unable to locate LifecycleProcessor with name 'lifecycleProcessor': using default [org.springframework.context.support.DefaultLifecycleProcessor@2f3fc03c]
    00:06:07,938 DEBUG DefaultListableBeanFactory:246 - Returning cached instance of singleton bean 'lifecycleProcessor'


    00:36:51,774 DEBUG DispatcherServlet:823 - DispatcherServlet with name 'spring' processing POST request for [/hpo/userHome.do]
11:00:56,266 DEBUG ResponseStatusExceptionResolver:132 - Resolving exception from handler [public org.springframework.web.servlet.ModelAndView com.hdo.spring.controller.BasicController.goHome(com.hdo.model.User,java.util.Map<java.lang.String, java.lang.Object>,javax.servlet.http.HttpServletRequest)]: java.lang.NullPointerException
11:00:56,267 DEBUG DefaultHandlerExceptionResolver:132 - Resolving exception from handler [public org.springframework.web.servlet.ModelAndView com.hdo.spring.controller.BasicController.goHome(com.hdo.model.User,java.util.Map<java.lang.String, java.lang.Object>,javax.servlet.http.HttpServletRequest)]: java.lang.NullPointerException
11:00:56,269 DEBUG DispatcherServlet:959 - Could not complete request
java.lang.NullPointerException
    at com.hdo.dao.GenericHibernateDAO.getCurrentSession(GenericHibernateDAO.java:27)
    at com.hdo.dao.GenericHibernateDAO.save(GenericHibernateDAO.java:33)
    at com.hdo.spring.controller.BasicController.goHome(BasicController.java:59)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)

我对spring mvc完全不熟悉我想我在这里处理多个问题,我将sessionFactory设置为[null]并将Rejected bean名称设置为“sessionFactory”。我试过在spring mvc3.2.2和hibernate4中使用所有最新的jar。我无法弄清楚这个问题是什么,所以请帮忙吗?

1 个答案:

答案 0 :(得分:10)

判断你的LocalSessionFactoryBean你可能混合了一些Hibernate 3和4的教程(它们的配置方式略有不同)。

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="com.hdo.model" /> <!-- assuming that is the package with your hibernate entities -->
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${jdbc.dialect}</prop>
            <prop key="hibernate.show_sql">${jdbc.showSql}</prop>
        </props>
    </property>
</bean>

我也缺少事务管理配置:

<tx:annotation-driven />

另一个错误是手动定义DAO bean,如果它已被component-scan选中:

<context:component-scan base-package="com.hdo.dao" />

最后 - 这种配置通常放在根Web应用程序上下文中。 Servlet应用程序上下文用于处理程序(控制器),处理程序映射,处理程序适配器和处理程序拦截器(如LocaleChangeInterceptor)。


更新您的更新代码中存在多个错误。让我们逐一介绍它们:

  • 错误1 :您正在web.xml中的根网络应用上下文加载servlet应用上下文。
  • 解决方案1 ​​:从上下文参数中删除spring-servlet.xml,然后删除弹簧servlet的空init-param(spring-servlet.xml是它将加载的默认名称。
  • 错误2 :servlet应用程序上下文中的组件扫描过宽。它还将加载属于根Web应用程序上下文的bean。
  • 解决方案2 :将servlet应用程序上下文中的组件扫描更改为<context:component-scan base-package="com.hdo.controller" />,并将另一个组件扫描添加到根应用程序上下文<context:component-scan base-package="com.hdo.dao" />(您还可以删除注释-config 声明,因为组件扫描会自动生成。
  • 错误3 :DAO的事务配置无法正常工作,因为您调用的是非注释方法,而后者又直接调用save方法。这不起作用,因为第二个直接呼叫不会通过TX AOP代理。
  • 解决方案3:删除createUser中的UserDAO方法并直接从控制器调用save方法。
  • 错误4 :您正在手动创建UserDAO bean。使用Spring等IoC容器时,需要让它注入依赖项。
  • 解决方案4 :在您的控制器中删除new UserDAO行并添加@Autowire UserDAO userDao;属性。 Spring会为你注入你的DAO实例。此类实例将初始化其依赖项(例如sessionFactory
  • 错误5 :您可能不明白自己在做什么。
  • 解决方案5 :如果您缺乏基本的Java和Spring知识,很难帮助您。您关于单个问题的问题将成为逐步教程帮助服务。请多投入一点时间学习基本原理。春天reference manuals是一个好的开始。我知道他们很长,你可能不会100%理解(我知道我没有;)),但是很好的时间阅读它们。