Consider the following: If you want an embedded database (H2, HSQL or Derby), please put it on the

Posted zev1n

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Consider the following: If you want an embedded database (H2, HSQL or Derby), please put it on the相关的知识,希望对你有一定的参考价值。

一、问题

在启动springboot项目中遇到如下问题:

Description:
Failed to configure a DataSource: ‘url’ attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class

Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).

这个问题其实是url和数据源配置错误问题,果断查看配置文件和依赖。

另外,本项目用的是mybatisPlus+mysql,使用默认连接池hakis

———————————————————————————————

二、原代码展示

1、配置文件

server:
  port: 9999
spring:
  redis:
    host: 127.0.0.1
    port: 6379
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/lkd_user?characterEncoding=utf-8&serverTimezone=UTC
    username: root
    password: root
经过校对,没有问题

2、依赖

<?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>
    <packaging>pom</packaging>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>
    <groupId>com.zb</groupId>
    <artifactId>mysec</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <!--redis依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!--fastjson依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.33</version>
        </dependency>
        <!--jwt依赖-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.0</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>
</project>
经过校对,暂时没有发现错误

———————————————————————————————

三、发现

发现没有存在明显的配置文件和依赖的问题,于是又看了下控制台打印日志,真正错误其实在上面,日志级别为warn。

2022-08-21 19:10:31.248 WARN 39656 — [ main] ConfigServletWebServerApplicationContext :
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘userDetailServiceImpl’: Unsatisfied dependency expressed through field ‘tbUserMapper’; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘tbUserMapper’ defined in file [D:\\maven\\spring\\springcloud\\mysec\\target\\classes\\com\\zb\\mapper\\TbUserMapper.class]: Unsatisfied dependency expressed through bean property ‘sqlSessionFactory’; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘sqlSessionFactory’ defined in class path resource [com/baomidou/mybatisplus/autoconfigure/MybatisPlusAutoConfiguration.class]: Unsatisfied dependency expressed through method ‘sqlSessionFactory’ parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘dataSource’ defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration H i k a r i . c l a s s ] : B e a n i n s t a n t i a t i o n v i a f a c t o r y m e t h o d f a i l e d ; n e s t e d e x c e p t i o n i s o r g . s p r i n g f r a m e w o r k . b e a n s . B e a n I n s t a n t i a t i o n E x c e p t i o n : F a i l e d t o i n s t a n t i a t e [ c o m . z a x x e r . h i k a r i . H i k a r i D a t a S o u r c e ] : F a c t o r y m e t h o d ′ d a t a S o u r c e ′ t h r e w e x c e p t i o n ; n e s t e d e x c e p t i o n i s o r g . s p r i n g f r a m e w o r k . b o o t . a u t o c o n f i g u r e . j d b c . D a t a S o u r c e P r o p e r t i e s Hikari.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties Hikari.class]:Beaninstantiationviafactorymethodfailed;nestedexceptionisorg.springframework.beans.BeanInstantiationException:Failedtoinstantiate[com.zaxxer.hikari.HikariDataSource]:FactorymethoddataSourcethrewexception;nestedexceptionisorg.springframework.boot.autoconfigure.jdbc.DataSourcePropertiesDataSourceBeanCreationException: Failed to determine a suitable driver class

这里打印了bean的依赖问题,如下:

userDetailServiceImpl——依赖——》tbUserMapperl——依赖——》 sqlSessionFactory——依赖——》MybatisPlusAutoConfiguration ——依赖——》dataSource——依赖——》jdbc.DataSourceProperties

这里最终原因是:Failed to determine a suitable driver class,翻译下就是:无法确定合适的驱动程序类。错误主要跟DataSource有关。

———————————————————————————————

四、找原因

1、查看DataSourceConfiguration类,看看导入的实际DataSource配置。

abstract class DataSourceConfiguration 
	//创建DataBase
	@SuppressWarnings("unchecked")
	protected static <T> T createDataSource(DataSourceProperties properties, Class<? extends DataSource> type) 
		return (T) properties.initializeDataSourceBuilder().type(type).build();
	
	
	/**
	 * Hikari DataSource configuration.
	 */
	@Configuration
	@ConditionalOnClass(HikariDataSource.class)
	@ConditionalOnMissingBean(DataSource.class)
	@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource",
			matchIfMissing = true)
	static class Hikari 

		@Bean
		@ConfigurationProperties(prefix = "spring.datasource.hikari")
		public HikariDataSource dataSource(DataSourceProperties properties) 
			HikariDataSource dataSource = createDataSource(properties, HikariDataSource.class);
			if (StringUtils.hasText(properties.getName())) 
				dataSource.setPoolName(properties.getName());
			
			return dataSource;
		
	//省略其他Database配置(tomcat 、dbcp2、generic)
	


这里断点,走的是HikariDataSource的dataSource()工厂方法,然后调用createDataSource()。

评估表达式(ALT+F8)计算createDataSource(),正好是导致异常的最终原因:

org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class

(断点的时候已经发现jdbc爆红,没有成功导入)

继续往下走,进入到DataSourceProperties类initializeDataSourceBuilder()

public DataSourceBuilder<?> initializeDataSourceBuilder() 
	return DataSourceBuilder.create(getClassLoader()).type(getType()).driverClassName(determineDriverClassName())
			.url(determineUrl()).username(determineUsername()).password(determinePassword());

这里采用建造者模式链式调用,方法依次为创建——》类型——》驱动类名——》URL——》用户名——》密码。

评估表达式(ALT+F8)递进式计算:链式调用的返回结果。发现链式调用到driverClassName(determineDriverClassName())报错,并且后面也的determine()全部报错。

(这里已经发现问题,猜测配置文件声明的DriverClassName、url、username、password没有被识别到)

继续往下走,进入到determineDriverClassName()方法

public String determineDriverClassName() 
		if (StringUtils.hasText(this.driverClassName)) 
			Assert.state(driverClassIsLoadable(), () -> "Cannot load driver class: " + this.driverClassName);
			return this.driverClassName;
		
		String driverClassName = null;
		if (StringUtils.hasText(this.url)) 
			driverClassName = DatabaseDriver.fromJdbcUrl(this.url).getDriverClassName();
		
		if (!StringUtils.hasText(driverClassName)) 
			driverClassName = this.embeddedDatabaseConnection.getDriverClassName();
		
		if (!StringUtils.hasText(driverClassName)) 
			//这里正好是控制台日志warn信息的最后一行提示
			throw new DataSourceBeanCreationException("Failed to determine a suitable driver class", this,
					this.embeddedDatabaseConnection);
		
		return driverClassName;
	

运行到这已经结束,错误信息中嵌套的最后异常就是出自这里

DataSourceBeanCreationException: Failed to determine a suitable driver class

断点中发现,该方法的类DataSourceProperties中的字段driverClassName、url、username、password全部为NULL。

于是又打开了其他运行正常的项目,断点上述各个位置,重新debug

首先进入到DataSourceConfiguration类的dataSource方法

可以看到,这个时候已经完成配置项的读取,往下走到DataSourceProperties类的initializeDataSourceBuilder()方法

这里并没有引发异常,同时发现determineXXX()方法都能得到对应的值。

到这,可以确定是配置信息没有成功被读取到,也就是YAML配置失效。

———————————————————————————————

五、解决方案

1、检查YAML文件位置、是否存在语法错误(四个配置项都没有成功读取,可以排除)

2、查看POM文件是否存在配置错误

最后发现问题是POM打包方式错误,多写了一行

    <modelVersion>4.0.0</modelVersion>
<!--    <packaging>pom</packaging>-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>

———————————————————————————————

六、建议

1、不用看mybatis的mapper接口和映射文件、实体类。

项目启动时没有查数据库,也就没有调用mapper层,自然不会引发这个错误。
就算报错上提示信息也很明确,网上很多说要检查这个,感觉没有必要。

2、看yml/properties配置文件中跟url相关的,是否存在错误。

配置写多了,基本不会出现语法或声明错误,而且有代码提示

3、多断点调试,没必要重复性检查代码是否写错,结果半天也找不出来。

Action: Consider the following: If you want an embedded database (H2, HSQL or Derby), please put it

错误原因

在pom中引入了mybatis-spring-boot-starter ,Spring boot默认会加载org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration类,DataSourceAutoConfiguration类使用了@Configuration注解向spring注入了dataSource bean。因为工程中没有关于dataSource相关的配置信息,当spring创建dataSource bean因缺少相关的信息就会报错。

解决错误
在Spring boot的启动引导类上增加属性@SpringBootApplication(exclude = DataSourceAutoConfiguration.class),即可阻止Spring boot自动注入dataSource
————————————————
版权声明:本文为CSDN博主「bug开发师」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lwj1433223/article/details/108000303

以上是关于Consider the following: If you want an embedded database (H2, HSQL or Derby), please put it on the的主要内容,如果未能解决你的问题,请参考以下文章

Spring boot 启动错误处理:Action: Consider the following: If you want an embedded database (H2, HSQL or Der

SThw2——find the error in the follow case

consider increasing the maximum size of the cache.

consider increasing the maximum size of the cache

Tomcat 警告:consider increasing the maximum size of the cache

pip install报错,“Consider using the `--user` option or check the permissions”