SpringBoot-创建在类路径资源中定义名为“ dataSource”的 bean 时出错

我有 SpringBootweb 应用程序。它以 REST 方法为中心。所有配置似乎都已到位,但由于某种原因,MainController 无法处理请求。结果是404错误。怎么补救?

@Controller
public class MainController {


@Autowired
ParserService parserService;


@RequestMapping(value="/", method= RequestMethod.GET)
public @ResponseBody String displayStartPage(){
return "{hello}";
}
}

申请

@Configuration
@ComponentScan(basePackages = "")
@EnableAutoConfiguration
public class Application extends SpringBootServletInitializer{
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}


@Override
protected final SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}

解析器控制器

@RestController
public class ParserController {


@Autowired
private ParserService parserService;


@Autowired
private RecordDao recordDao;


private static final Logger LOG = Logger.getLogger(ParserController.class);


@RequestMapping(value="/upload", method= RequestMethod.POST)
public @ResponseBody String fileUploadPage(
}
}

更新

看起来好像 MySQL 不能被 Spring 初始化... ..。

    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Injection of autowired dependencies failed;


nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.dataSource;


nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]: Instantiation of bean failed;


nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.sql.DataSource org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$NonEmbeddedConfiguration.dataSource()] threw exception;


nested exception is org.springframework.beans.factory.BeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath.

更新2

应用性能

    # Database
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/logparser
spring.datasource.username = root
spring.datasource.password = root
    

spring.jpa.database = MYSQL
spring.jpa.show-sql = true
    

# Hibernate
hibernate.dialect: org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql: true
hibernate.hbm2ddl.auto: update
entitymanager.packagesToScan: /

更新资料4

似乎轻型控制器没有响应,即使 @RequestMapping设置。为什么会这样呢?

另外,当我运行 Maven 的生命周期 test时会出现这种情况。 在 IntelliJ 中以 degub 模式运行时,没有输出错误。

更新5

此外,我还使用了教程中解释的 DAO... 。

public interface RecordDao extends CrudRepository<Record, Long> {
}

Http://blog.netgloo.com/2014/10/27/using-mysql-in-spring-boot-via-spring-data-jpa-and-hibernate/

更新资料6

我改变了我的应用程序属性。尝试了每一个组合,但它拒绝工作

Maven 输出:

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running IntegrationTest
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 2.365 sec <<< FAILURE! - in IntegrationTest
saveParsedRecordsToDatabase(IntegrationTest)  Time elapsed: 2.01 sec  <<< ERROR!
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:101)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:331)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:213)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:290)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:292)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:233)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:87)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:176)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:264)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:124)
at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:200)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:153)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.dataSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.sql.DataSource org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$NonEmbeddedConfiguration.dataSource()] threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath.
638374 次浏览

From the looks of things you haven't passed enough data to Spring Boot to configure the datasource

Create/In your existing application.properties add the following

spring.datasource.driverClassName=
spring.datasource.url=
spring.datasource.username=
spring.datasource.password=

making sure you append a value for each of properties.

The hibernate.* properties are useless, they should be spring.jpa.* properties. Not to mention that you are trying to override those already set by using the spring.jpa.* properties. (For the explanation of each property I strongly suggest a read of the Spring Boot reference guide.

spring.jpa.database-platform = org.hibernate.dialect.MySQL5Dialect
spring.jpa.show-sql = true


# Hibernate
spring.jpa.hibernate.ddl-auto=update

Also the packages to scan are automatically detected based on the base package of your Application class. If you want to specify something else use the @EntityScan annotation. Also specifying the most toplevel package isn't really wise as it will scan the whole class path which will severely impact performance.

Maybe you forgot the MySQL JDBC driver.

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
</dependency>

Looks like the initial problem is with the auto-config.

If you don't need the datasource, simply remove it from the auto-config process:

@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})

Edit: If using @SpringBootApplication in your main class:

@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})

Are you running the application as a jar? ( java -jar xxxx.jar)

If so, do you have the application.properties stored in that jar ?

If no, try to figure out why :

  • To be automatically package in the jar, the files can be in : src/main/resources/application.properties
  • The maven plugin in the pom.xml can also be configured

In my case this was happening because org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.dataSource is an autowired field without a Qualifier and I am using multiple datasources with qualified names. I solved this problem by using @Primary arbitrarily on one of my dataSource bean configurations like so

@Primary
@Bean(name="oneOfManyDataSources")
public DataSource dataSource() { ... }

I suppose they want you to implement AbstractRoutingDataSource, and then that auto configuration will just work because no qualifier is needed, you just have a single data source that allows your beans to resolve to the appropriate DataSource as needed. Then you don't need the @Primary or @Qualifier annotations at all, because you just have a single DataSource.

In any case, my solution worked because my beans specify DataSource by qualifier, and the JPA auto config stuff is happy because it has a single primary DataSource. I am by no means recommending this as the "right" way to do things, but in my case it solved the problem quickly and did not deter the behavior of my application in any noticeable manner. Will hopefully one day get around to implementing the AbstractRoutingDataSource and refactoring all the beans that need a specific DataSource and then perhaps that will be a neater solution.

I was getting the same error, found out it was due to some of the dependencies missing in my pom.xml like that of Spring JPA, Hibernate, Mysql or maybe Jackson. So make sure that dependencies are not missing in your pom.xml and check their version compatibility.

<!-- Jpa and hibernate -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.0.3.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>

It worked for me you can try your: Add this to VM options in Tomcat

-DdevBaseDir="C:\Your_Project_Dir_Path"

change below line of code

spring.datasource.driverClassName

to

spring.datasource.driver-class-name

I was facing this issue even after supplying all required datasource properties in application.properties. Then I realized that properties configuration class was not getting scanned by Spring boot because it was in different package hierarchy compared to my Spring boot Application.java and hence no properties were applied to datasource object. I changed the package name of my properties configuration class and it started working.

If you're using application.properties in spring boot app, then just put the below line into application.properties and it should work:
spring.datasource.url: jdbc:mysql://google/?cloudSqlInstance=&socketFactory=com.google.cloud.sql.mysql.SocketFactory&user=****&password=****

In my case I just ignored the following in application.properties file:

# Hibernate

#spring.jpa.hibernate.ddl-auto=update

It works for me....

Check that you have database dependency at runtime group at build.gradle

runtime group: 'com.h2database', name: 'h2', version: '1.4.194'

or change scope from test to runtime if you use Maven

<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.194</version>
<scope>runtime</scope>
</dependency>

Give you something different, when you encounter this kind of error, cannot create bean datasource in a test case.

It might be caused by some reasons:

  1. No datasource, you will need to create your datasource, h2 in-memory datasource or whatever, or you can choose the way like exclude={datasource··}.
  2. You have your datasource, like MySQL, but it still not work. It was caused by class AutoConfigureTestDatabase, It will choose a datasource for you which may cause ambiguity.

Solution: add @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) to avoid replace the default datasource.

Not directly related to the original question but this will be useful for someone. This error occurred to me with a simple two project structure. One project was handling some database operations with spring JDBC (say A) and the other did not have any JDBC operations at all(say B). But still, this error appeared while I was starting service B. Saying the datasource should be initialized properly.

As I figured out I had added this dependency to the parent pom of the two modules

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

This caused spring to initialize the JDBC dependencies for project B too. So, I moved it to project A's pom, everything was fine.

Hope this would help someone

This problem comes while you are running Test. Add dependency

testCompile group: 'com.h2database', name: 'h2', version: '1.4.197'

Add folder resources under test source add file bootstrap.yml and provide content.

spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:h2:mem:TEST
driver-class-name: org.h2.Driver
username: username
password: password
hikari:
idle-timeout: 10000

this will setup your data source.

I was facing the same problem for several days, and finally the issue isn't with the code, the problem commes from maven, you must delete all the files that he downloaded from your hard drive "C:\Users\username.m2\repository", and do another update maven for your project, that will fix your problem.

I solved my problem with the change of the parent Spring Boot Dependency.

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
</parent>

to

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
</parent>

For more Information, take a look at the release notes: Spring Boot 2.1.0 Release Notes

Created database in MySQL

create database springboot2;

application.properties

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/springboot2
spring.datasource.username = root
spring.datasource.password = root
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
server.port=9192

pom.xml

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


<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

main class

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
public class Application {


public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}


}

model class

package com.First.Try.springboot.entity;
    

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name="PRODUCT_TBL1")
public class Product {
@Id
@GeneratedValue
private int id;
private String name;
private int quantity;
private double price;
....
....
....
}

By default, with the latest version of Spring Boot, the load of data.sql is done before the tables are created. So use - spring.jpa.defer-datasource-initialization=true

Example -

**In application.properties :- **
spring.jpa.show-sql=true
spring.datasource.url=jdbc:h2:mem:testdb
spring.h2.console.enabled=true
spring.jpa.defer-datasource-initialization=true

Thanks Athar Karim

I am working with spring boot 2.6.0 I tried several answers and they were not enough. One temporal solution I found was this

@SpringBootApplication(exclude = SqlInitializationAutoConfiguration.class)

Although it lets the server run and the h2-console appear I could not connect to my data.sql file. This was the error I got

Database "mem:testdb" not found, either pre-create it or allow remote database creation (not recommended in secure environments) [90149-200] 90149/90149

This is the solution I found (Some have already been)Add these lines to the application.properties file

spring.jpa.show-sql=true
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testdb
spring.jpa.defer-datasource-initialization=true

Save an re-run the server then try to access the db on the browser again from the h2-console

By default, data.sql scripts are now run before Hibernate is initialized. This aligns the behavior of basic script-based initialization with that of Flyway and Liquibase. If you want to use data.sql to populate a schema created by Hibernate, set spring.jpa.defer-datasource-initialization to true.

spring.jpa.defer-datasource-initialization=true solves the issue

I have not used h2 configuration in pom file.I have added it and this problem was solved.

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

Seems you are having a problem with datasource. If you don't need the datasource, simply disable it using

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
 

Just put this in your application.properties

If you are using mysql you need 2 dependencies

1

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


    

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

If you are using potgress you only need :

1.

<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>

using h2 and you need to add data.sql just make sure you add

spring.jpa.defer-datasource-initialization=true

on the application.properties.

This is my application.properties file:

spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.defer-datasource-initialization=true
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.h2.console.settings.trace=false
spring.h2.console.settings.web-allow-others=false

I'm using IntelliJ community edition with DB Browser Plugin

It works for me...

To resolve this issue give the primary key column value @NotNull not NULL annotation and it would work.

In my case, I had inserted a record in a table in data.sql, but that table's name was incorrect in schema.sql, where I had created that table.

Please add the below dependency to get rid of this.

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

make sure you add all the dependencies in your pom.xml

 <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</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-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>