我正在开发一个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>
答案 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正在扫描类以放入其上下文。