java - 当我使用@Autowired时出现空错误

标签 java mysql spring jdbctemplate

感谢您阅读本文。我是 Spring Java 的新手。 我正在尝试根据现有项目做一个项目。当我使用EmbeddedDatabase时,一切都很好。但是当我更改为SQL数据库时,当我尝试@Autowired NamedParameterJDBCTemplate时遇到了这个问题。 这是我的代码:

pom.xml

<properties>
        <jdk.version>1.8</jdk.version>
        <spring.version>4.3.9.RELEASE</spring.version>
        <springframework.version>4.3.9.RELEASE</springframework.version>
        <mysql.connector.version>5.1.31</mysql.connector.version>
        <logback.version>1.1.3</logback.version>
        <jcl.slf4j.version>1.7.12</jcl.slf4j.version>
        <jstl.version>1.2</jstl.version>
        <servletapi.version>3.1.0</servletapi.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- Spring Web -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- Spring Web <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> 
            <version>${spring.version}</version> </dependency> -->

        <!-- Spring Framework -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <version>1.4.3.RELEASE</version>
        </dependency>

        <!-- Hibernate -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.3.6.Final</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${jcl.slf4j.version}</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
        </dependency>

        <!-- jstl -->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>${jstl.version}</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${servletapi.version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>

        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.1</version>
        </dependency>

        <!-- jsr303 validation -->
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.1.3.Final</version>
        </dependency>

        <!-- MySQL -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.connector.version}</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>${jdk.version}</source>
                    <target>${jdk.version}</target>
                </configuration>
            </plugin>

            <!-- embedded Jetty server, for testing -->
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.2.11.v20150529</version>
                <configuration>
                    <scanIntervalSeconds>10</scanIntervalSeconds>
                    <webApp>
                        <contextPath>/project</contextPath>
                    </webApp>
                </configuration>
            </plugin>

            <!-- configure Eclipse workspace -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.9</version>
                <configuration>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>true</downloadJavadocs>
                    <wtpversion>2.0</wtpversion>
                    <wtpContextName>project</wtpContextName>
                </configuration>
            </plugin>

            <!-- Tomcat plugin -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat8.5-maven-plugin</artifactId>
                <version>2.2</version>
                <!-- Config: contextPath and Port (Default: /SpringMVCSocialJdbc : 8080) -->
                <!-- <configuration> <path>/</path> <port>8899</port> </configuration> -->
            </plugin>
        </plugins>
    </build>

文件配置MYSQL数据库

package com.project.form.config;

import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@EnableTransactionManagement
@ComponentScan({ "com.project.form.config","com.project.form.dao" })
@PropertySource(value = { "classpath:application.properties" })
@Configuration
public class SpringDBConfig {
//  @Autowired
//  DataSource dataSource;

    DriverManagerDataSource db;

    NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    @Autowired
    private Environment environment;

    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(getDataSource());
        sessionFactory.setPackagesToScan(new String[] { "com.project.form.model" });
        sessionFactory.setHibernateProperties(hibernateProperties());
        return sessionFactory;
    }

    private Properties hibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
        properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
        properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
        return properties;
    }

    @Bean
    public DataSource getDataSource() {
        db = new DriverManagerDataSource();
        db.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
        db.setUrl(environment.getRequiredProperty("jdbc.url"));
        db.setUsername(environment.getRequiredProperty("jdbc.username"));
        db.setPassword(environment.getRequiredProperty("jdbc.password"));
        System.out.println("## getDataSource: " + db);
        return db;
    }

    @Bean
    public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {
        if(db!=null){
            System.out.println("Not Null!");
        }
        return new NamedParameterJdbcTemplate(db);
    }

    @Bean
    @Autowired
    public HibernateTransactionManager transactionManager(SessionFactory s) {
        HibernateTransactionManager txManager = new HibernateTransactionManager();
        txManager.setSessionFactory(s);
        return txManager;
    }
}

文件属性。

 #jdbc
 jdbc.driverClassName=com.mysql.jdbc.Driver
 jdbc.url=jdbc:mysql://localhost:3306/motsach
 jdbc.username=root
 jdbc.password=123456

 #hibernate
 hibernate.dialect=org.hibernate.dialect.MySQLDialect
 hibernate.show_sql=true
 hibernate.format_sql=true

这就是我的问题所在。当我输入@Autowired时,出现错误!

@Repository
public class BookDaoImpl implements BookDao {

    NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    @Autowired <-- HERE IS THE ERROR!
    public void setNamedParameterJdbcTemplate(NamedParameterJdbcTemplate namedParameterJdbcTemplate) throws DataAccessException {
        this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
    }

    @Override
    public List<Book> findAll() {
        // TODO Auto-generated method stub
        String sql = "SELECT * FROM books";
        List<Book> result = namedParameterJdbcTemplate.query(sql, new BookMapper());
        return null;
    }
    private static final class BookMapper implements RowMapper<Book> {
        public Book mapRow(ResultSet rs, int rowNum) throws SQLException {
            Book book = new Book();
            book.setId(rs.getInt("id"));
            book.setTensach(rs.getString("tensach"));
            book.setTacgia(rs.getString("tacgia"));
        book.setTheloai(convertDelimitedStringToList(rs.getString("theloai")));
            book.setTinhtrang(rs.getString("tinhtrang"));
            return book;
    }
}

这是我的模型文件:

@DynamicUpdate
@Table(name="books")
public class Book implements java.io.Serializable {
    private static final long serialVersionUID = 1L;

Integer book_ID;

String tensach;

String tacgia;

String nhanxet;

String tinhtrang;

List<String> theloai;

@Id
@GeneratedValue(strategy= IDENTITY)
@Column(name = "id", unique = true, nullable=false)
public Integer getId() {
    return book_ID;
}

public void setId(Integer id) {
    this.book_ID = id;
}

@Column(name ="tensach", length = 50,nullable=true)
public String getTensach() {
    return tensach;
}

public void setTensach(String tensach) {
    this.tensach = tensach;
}

@Column(name ="tacgia", length = 50,nullable=true)
public String getTacgia() {
    return tacgia;
}

public void setTacgia(String tacgia) {
    this.tacgia = tacgia;
}

@Column(name ="nhanxet", length = 50,nullable=true)
public String getNhanxet() {
    return nhanxet;
}

public void setNhanxet(String nhanxet) {
    this.nhanxet = nhanxet;
}

@Column(name ="tinhtrang", length = 50,nullable=true)
public String getTinhtrang() {
    return tinhtrang;
}

public void setTinhtrang(String tinhtrang) {
    this.tinhtrang = tinhtrang;
}

@Column(name ="theloai", length = 50,nullable=true)
public List<String> getTheloai() {
    return theloai;
}

public void setTheloai(List<String> theloai) {
    this.theloai = theloai;
}

public boolean isNew() 
{
    return (this.book_ID ==null);
}

@Override
public String toString() {
    return "Book [id=" + book_ID + ", tensach=" + tensach + ", tacgia=" + tacgia + ", nhanxet=" + nhanxet
            + ", tinhtrang=" + tinhtrang + ", theloai=" + theloai + "]" + isNew();
}

这是错误:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getNamedParameterJdbcTemplate' defined in com.project.form.config.SpringDBConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate]: Factory method 'getNamedParameterJdbcTemplate' threw exception; nested exception is java.lang.IllegalArgumentException: DataSource must not be null
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
        at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:659)
        ... 71 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate]: Factory method 'getNamedParameterJdbcTemplate' threw exception; nested exception is java.lang.IllegalArgumentException: DataSource must not be null
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
        ... 83 more
Caused by: java.lang.IllegalArgumentException: DataSource must not be null
        at org.springframework.util.Assert.notNull(Assert.java:134)
        at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.<init>(NamedParameterJdbcTemplate.java:91)
        at com.project.form.config.SpringDBConfig.getNamedParameterJdbcTemplate(SpringDBConfig.java:68)
        at com.project.form.config.SpringDBConfig$$EnhancerBySpringCGLIB$$74cd0411.CGLIB$getNamedParameterJdbcTemplate$3(<generated>)
        at com.project.form.config.SpringDBConfig$$EnhancerBySpringCGLIB$$74cd0411$$FastClassBySpringCGLIB$$fca131ea.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
        at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358)
        at com.project.form.config.SpringDBConfig$$EnhancerBySpringCGLIB$$74cd0411.getNamedParameterJdbcTemplate(<generated>)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
        ... 84 more

谢谢大家!

最佳答案

尝试使用此配置:

@EnableTransactionManagement
@ComponentScan({ "com.project.form.config","com.project.form.dao" })
@PropertySource(value = { "classpath:application.properties" })
@Configuration
public class SpringDBConfig {

    @Autowired
    private Environment environment;

    @Bean
    public LocalSessionFactoryBean sessionFactory(DataSource db) {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(db);
        sessionFactory.setPackagesToScan(new String[] { "com.project.form.model" });
        sessionFactory.setHibernateProperties(hibernateProperties());
        return sessionFactory;
    }

    private Properties hibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
        properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
        properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
        return properties;
    }

    @Bean
    public DataSource getDataSource() {
        DriverManagerDataSource db = new DriverManagerDataSource();
        db.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
        db.setUrl(environment.getRequiredProperty("jdbc.url"));
        db.setUsername(environment.getRequiredProperty("jdbc.username"));
        db.setPassword(environment.getRequiredProperty("jdbc.password"));
        System.out.println("## getDataSource: " + db);
        return db;
    }

    @Bean
    public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate(DataSource db) {
        if(db!=null){
            System.out.println("Not Null!");
        }
        return new NamedParameterJdbcTemplate(db);
    }

    @Bean
    public HibernateTransactionManager transactionManager(SessionFactory s) {
        HibernateTransactionManager txManager = new HibernateTransactionManager();
        txManager.setSessionFactory(s);
        return txManager;
    }
}

正如异常消息中所解释的,Spring IoC 容器无法创建 NamedParameterJdbcTemplate 的实例,因为尚未实例化 DataSource...

Spring IoC容器按照一定的顺序实例化配置类中声明的bean。此顺序是根据每个 bean 声明的依赖关系推导出来的。

在您的原始配置类中,您没有将 DataSource 声明为 getNamedParameterJdbcTemplate bean 的依赖项,因此可能没有 DataSource 的实例> 准备注入(inject)...

注意:如果您通过@Bean注释声明bean,则不需要同时使用@Autowired:方法参数将自动连接。

关于java - 当我使用@Autowired时出现空错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45977119/

相关文章:

java - 我将如何定义无限数量的变量? * java *

php - MySQL加入及最新批处理信息

c# - 在gridview中搜索和显示

java - 一对多的连接列为 null hibernate

spring - 如何使用@Autowired像工厂模式一样动态注入(inject)实现

java - 如何跳过其他库日志到我的 log4j 记录器

java - 将 Java(Spring、Hibernate、MySql)项目从 Windows 迁移到 Debian

java - 当依赖属性更改时如何在实体上设置 ModifiedDate

mysql - 从 phpMyAdmin 转储中删除 DELIMITER

java - 如何使用 Spring 配置基于属性文件配置一个实现?