0

我正在使用自动装配会话工厂的 GenricHibernateDAO,当我通过控制器调用 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);
        }
    }

用户道:

@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(属性)

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

spring-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>

应用程序上下文.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>

网页.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]并拒绝了bean名称'sessionFactory'。我尝试在 spring mvc3.2.2 和 hibernate4 中使用所有最新的 jar。我无法弄清楚是什么问题,所以请帮忙?

4

1 回答 1

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.
  • 解决方案 1spring-servlet.xml从 context-param 中删除并删除spring 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" />(您也可以删除annotation-config声明,因为组件扫描会自动附带)。
  • 错误 3:DAO 的事务配置将不起作用,因为您正在调用非注释方法,而后者又直接调用 save 方法。这将不起作用,因为第二次直接调用不会通过 TX AOP 代理。
  • 解决方案3:删除您的createUser方法UserDAO并直接从控制器调用保存方法。
  • 错误 4:您正在UserDAO手动创建 bean。使用 Spring 等 IoC 容器时,您需要让它注入您的依赖项。
  • 解决方案 4:在您的控制器中删除该new UserDAO行并添加@Autowire UserDAO userDao;属性。Spring 将为您注入您的 DAO 实例。sessionFactory这样的实例将初始化其依赖项(例如)。
  • 错误5:你可能不明白你在做什么。
  • 解决方案 5:如果您缺乏基本的 Java 和 Spring 知识,很难帮助您。您关于单个问题的问题成为分步教程帮助服务。请多花一点时间来学习基本原理。Spring参考手册是一个好的开始。我知道它们很长,你可能不会 100% 理解(我知道我不理解 ;)),但花时间阅读它们是值得的。
于 2013-06-16T20:18:23.583 回答