org.springframework.beans.factory.BeanCreationException:创建名为' queryRepository'的bean时出错

时间:2016-08-11 22:47:47

标签: java spring-boot

我正在开发一个Spring-Boot应用程序来连接数据库。我的问题与无法自动装配和JdbcTemplate有关。我对自动装配和JdbcTemplate的理解是有限的,所以错误确实可能是任何事情。解释错误,如何解决,以及如何避免将来出现这些/这些问题将不胜感激。

我遗漏了我的sql文件和application.properties,因为它们与自动装配问题无关。

另外,如果不是太麻烦,有人可以解释自动装配的概念吗?我看过这个网站上的人们解释这个概念的帖子,但我还是不太了解它。我知道自动装配会自动执行某些操作。我相信创建一个bean并用一些信息填充它,但这就是它。

堆栈追踪:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'queryRepository': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.jdbc.core.JdbcTemplate edu.ucdavis.QueryRepository.jdbcTemplate; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.jdbc.core.JdbcTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839) ~[spring-context-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) ~[spring-context-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) ~[spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:760) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:360) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:306) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1185) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1174) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at edu.ucdavis.QuickControllerApplication.main(QuickControllerApplication.java:20) [classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_92]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_92]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_92]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_92]
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) [idea_rt.jar:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.jdbc.core.JdbcTemplate edu.ucdavis.QueryRepository.jdbcTemplate; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.jdbc.core.JdbcTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Query.java

**************************************************************
 * Query.java - This object should hold all the information that
 * the person is looking for in their query search.
 **************************************************************/

package edu.ucdavis.objects;

import edu.ucdavis.ProjectConstants;

import java.io.*;
import java.util.Date;

/**************************************************************
 * queryIDNumber - a long that holds the individual data of an
 * individual query. Each query will have a unique number
 * associated with it.
 **************************************************************/
public class Query {
    private Long queryID;           //each query must have a unique ID Number which will go in the URL when the user is viewing the result of the query search.
    private static Long totalQueryIDs = 0L;      //holds the value of how many queries have been created over the life of the program
    private static Long largestIDNumber = 1L;    //holds the largest possible ID that the program knows of; used as a check

    public Query()
    {
        this.queryID = generateQueryID();
        updateOutputFile(this.queryID);
    }

    public Query(Long generatedIDNumber){
        this.queryID = generatedIDNumber;
        updateOutputFile(this.queryID);
    }

    /**************************************************************
     * generateQueryID - Generate a ID Number for a query. ID
     * Number must be unique, and then is assigned to queryID
     **************************************************************/
    public Long generateQueryID(){
        Long generatedNumber;

        //Finds the totalQueryIDs stored in QUERY_COUNT_FILE
        generatedNumber = findNumberOfQueries();

        //System.out.println("generatedNumber " + generatedNumber + "\n");

        //generatedNumber is not a legal value, so assigning the default minimum
        if (generatedNumber < ProjectConstants.MIN_ID_NUMBER){
            totalQueryIDs = ProjectConstants.MIN_ID_NUMBER;
        }
        //if the next available number has not been used, increase totalQueryIDs
        else if(largestIDNumber < generatedNumber) {
            largestIDNumber = generatedNumber;
            totalQueryIDs = generatedNumber;
        }

        return queryID = totalQueryIDs;
    }

    public Long getQueryID(){
        return queryID;
    }

    public Long getTotalQueryIDs(){
        return totalQueryIDs;
    }

    public void setTotalQueryIDs(Long number){
        totalQueryIDs = number;
    }

    public void setQueryID(Long number){
        queryID = number;
    }

    public void setLargestIDNumber(Long number){
        largestIDNumber = number;
    }

    /**************************************************************
     * findNumberOfQueries - This function finds out how many
     * queries have been generated so far. This function will check
     * a text file that will contain the past number of queries
     * that have been generated.
     **************************************************************/
    public Long findNumberOfQueries(){
        //Check a file. If queryCountFile.txt is not found then numberOfQueries is considered 0 and becomes 1?
        try {
            //Assume default encoding.
            File file = new File(ProjectConstants.QUERY_COUNT_FILE);
            //FileWriter fileWriter = new FileWriter(file);
            FileReader fileReader = new FileReader(file);

            //Always wrap FileReader in BufferedReader.
            BufferedReader bufferedReader = new BufferedReader(fileReader);

            try{
                //System.out.println("got here\n");   //debug statement
                String line;    //temp var

                //skip first SKIP_NUM_LINES_IN_FILE lines in QUERY_COUNT_FILE
                for (int count = 0; count < ProjectConstants.SKIP_NUM_LINES_IN_FILE; count++) {
                    line = bufferedReader.readLine();
                    //System.out.print(line);         //debug statement
                }

                line = bufferedReader.readLine();
                //System.out.println("This is the value of line " + line);        //debug
                while (line != null) {
                    //System.out.println("stuff bufferedReader got: " + line);    //debug
                    totalQueryIDs = Long.parseLong(line);
                    line = bufferedReader.readLine();
                }
            }
            catch(IOException ex) {
                System.out.println("Error reading to file '" + ProjectConstants.QUERY_COUNT_FILE + "'");
            }

            //Close the file.
            bufferedReader.close();
        }
        catch(IOException ex) {
            System.out.println("Error writing to file '" + ProjectConstants.QUERY_COUNT_FILE + "'");
        }

        return totalQueryIDs;
    }

    /**************************************************************
     * updateOutputFile - This function will update QUERY_COUNT_FILE
     * with the new totalQueryIDs as a result of recently creating
     * a Query object.
     **************************************************************/
    public void updateOutputFile(Long IDNumber) {
        try {
            Date date = new Date();

            //Assume default encoding.
            FileWriter fileWriter = new FileWriter(ProjectConstants.QUERY_COUNT_FILE);

            //Always wrap FileWriter in BufferedWriter.
            BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);

            bufferedWriter.write("FILE LAST WRITTEN TO ON: " + date + "\n");
            bufferedWriter.write("totalQueryIDs:\n");
            //Need to check the value of the incoming ID against holderOfUniqueIDs that holds all other IDs (the size) to make sure that the new query isn't overriding totalQueryIDs
            //MAYBE do it like this...
            if (largestIDNumber < IDNumber){
                bufferedWriter.write(Long.toString(IDNumber));
                largestIDNumber = IDNumber;
                totalQueryIDs = IDNumber;
            }else {
                bufferedWriter.write(Long.toString(largestIDNumber));
            }

            //Close the file.
            bufferedWriter.flush();
            bufferedWriter.close();

        } catch (IOException ex) {
            System.out.println("Error writing to file '" + ProjectConstants.QUERY_COUNT_FILE + "'");
        }
    }
}

ProjectConstants.java

/**************************************************************
 * This file holds the constants used throughout the program
 **************************************************************/

package edu.ucdavis;

public class ProjectConstants {


    public static final Long MIN_ID_NUMBER = 1L;  //minimum ID Number that can be ever generated by the program
    public static final String QUERY_COUNT_FILE = "queryCountFile.txt";       //this file will simply hold a number that states how many queries have been created
    public static final int SKIP_NUM_LINES_IN_FILE = 2;   //the first X number of lines that will skipped in QUERY_COUNT_FILE
    //public static final Long MAX_ID_NUMBER = 9223372036854775807L; //maximum ID Number that can be ever generated by the program
}

QuickControllerApplication.java

/**************************************************************
 * This Spring Boot project should make a controller that can
 * quickly search a database.
 **************************************************************/

package edu.ucdavis;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class QuickControllerApplication {

    public static void main(String[] args) {
        QuickController quickController = new QuickController();
        quickController.populateOutputFile(ProjectConstants.QUERY_COUNT_FILE);
        SpringApplication.run(QuickControllerApplication.class, args);
        //everthing below this line is for testing purposes
        //Query littleQuery = new Query(3L);

        //littleQuery.testPrint();
        //System.out.println("Num of findNumberOfQueries() " + littleQuery.findNumberOfQueries());
    }
}

QuickControllerApplicationTests.java

package edu.ucdavis;

import edu.ucdavis.objects.Query;

import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

import org.junit.*;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(QuickControllerApplication.class)
public class QuickControllerApplicationTests {
    @Autowired
    private QueryRepository queryRepository;

    @org.junit.Test
    public void findAllUsers() {
        List<Query> queries = queryRepository.findAll();
        Assert.assertNotNull(queries);
        Assert.assertTrue(!queries.isEmpty());
    }

    @Test
    public void findQueryById() {
        Query query = queryRepository.findQueryById(1L);
        Assert.assertNotNull(query);
    }

    /*@Test
    public void createUser() {
        Query query = new Query(1L);
        Query savedUser = queryRepository.create(query);
        Query newUser = queryRepository.findUserById(savedUser.getQueryID());
        Assert.assertNotNull(newUser);
        Assert.assertEquals("John", newUser.getName());
        Assert.assertEquals("john@gmail.com", newUser.getEmail());
    }
    */
}

QueryRepository.java

package edu.ucdavis;

import edu.ucdavis.objects.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.sql.*;
import java.util.List;

@Repository
public class QueryRepository {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Transactional
    public List<Query> findAll(){
        return jdbcTemplate.query("select * from queries", new QueryRowMapper());

    }
    @Transactional(readOnly = true)
    public Query findQueryById(Long id){
        return jdbcTemplate.queryForObject("select * from queries where id=?", new Object[]{id}, new QueryRowMapper());
    }

    /*public Query create(final Query query){
        final String sql = "insert into queries(queryID,totalQueryIDs) values(?,?)";

        KeyHolder holder = new GeneratedKeyHolder();
        jdbcTemplate.update(new PreparedStatementCreator() {
            @Override
            public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
                ps.setLong(1, query.getQueryID());
                ps.setLong(2, query.getTotalQueryIDs());
                return ps;
            }
        }, holder);

        int newUserId = holder.getKey().intValue();
        query.setQueryID(Integer.toUnsignedLong(newUserId) );
        return query;
    }
    */
}

class QueryRowMapper implements RowMapper<Query> {
    @Override
    public Query mapRow(ResultSet rs, int rowNum) throws SQLException {
        Query query = new Query();
        query.setQueryID(rs.getLong("queryID"));
        query.setTotalQueryIDs(rs.getLong("totalQueryIDs"));
        query.setLargestIDNumber(rs.getLong("largestIDNumber"));
        return query;
    }
}

的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>edu.ucdavis</groupId>
    <artifactId>QuickController</artifactId>
    <version>0.1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>QuickController</name>
    <description>This Spring Boot project should make a controller that can quickly search a database. This project was created by Michael Layman.</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

2 个答案:

答案 0 :(得分:0)

您需要在xml config或java config中定义JdbcTemplate bean,但是您创建的bean xml可能看起来像

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
    p:dataSource-ref="dataSource" 
/>

答案 1 :(得分:0)

我更喜欢用配置类ex:

创建它,而不是xml文件
@Configuration

公共课JpaConfig {

@Bean
public JdbcTemplate dataSource() {

   JdbcTemplate myJdbcTemplate = (your new custom instance)

    return myJdbcTemplate;
}

}

我似乎你正在使用Spring Boot,所以要注意你要放置“JpaConfig”类的地方,它必须是可见的,而spring正在扫描类以放入其上下文。