连接数据库Spring引导时出错

时间:2022-09-11 12:58:13

Helo I have been trying to connect to a database with Spring Boot for a while and I keep getting the error:

Helo我一直试图用Spring Boot连接数据库一段时间,我不断收到错误:

java.sql.SQLException: The url cannot be null

java.sql.SQLException:url不能为null

I am not sure what is it that I am doing wrong. The reason I am trying to get the configuration like this is because I want to use the encoded password for the database.

我不确定我做错了什么。我试图获得这样的配置的原因是因为我想使用数据库的编码密码。

This is what my files look like:

这就是我的文件的样子:

DataConfig.java

@Configuration
public class DataConfig {

    @Autowired
    private Environment env;

    @Configuration
    @Profile(value = "dev")
    public class DevPlaceHolderConfig {

        @Bean
        DataSource dataSource() {

            return DataSourceBuilder
                    .create()
                    .username(env.getProperty("spring.datasource.username"))
                    .password(env.getProperty("spring.datasource.password"))
                    .url(env.getProperty("spring.datasource.url"))
                    .driverClassName(env.getProperty("spring.datasource.driver-class-name"))
                    .build();
        }
    }

    @Configuration
    @Profile(value = "prod")
    public class ProdPlaceHolderConfig {
        @Bean
        DataSource dataSource() {

            return DataSourceBuilder
                    .create()
                    .username(env.getProperty("spring.datasource.username"))
                    .password(env.getProperty("spring.datasource.password"))
                    .url(env.getProperty("spring.datasource.url"))
                    .driverClassName(env.getProperty("spring.datasource.driver-class-name"))
                    .build();
        }
    }
}

EncryptorConfig.java

@Configuration
public class EncryptorConfig {

    @Bean
    public EnvironmentStringPBEConfig environmentVariablesConfiguration() {
        EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
        config.setAlgorithm("PBEWithMD5AndDES");
        config.setPasswordEnvName("APP_ENCRYPTION_PASSWORD");
        return config;
    }

    @Bean
    public PooledPBEStringEncryptor stringEncryptor() {
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        encryptor.setConfig(environmentVariablesConfiguration());
        return encryptor;
    }
}

application.yml

spring:
  profiles:
    active: prod
  output:
    ansi:
      enabled: always
---
spring:
  profiles: dev
  application:
    name: App-Dev
  datasource:
    url: jdbc:mysql://localhost:3306/database?useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver 
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL5Dialect
server:
  port: 8080

---

spring:
  profiles: prod
  application:
    name: App-Prod
  datasource:
    url: jdbc:mysql://localhost:3306/database?useSSL=false
    username: root
    password: ENC(/98CfxmsjKBW5oZsLkLlmw==)
    driver-class-name: com.mysql.jdbc.Driver 
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: none
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL5Dialect
server:
  port: 3000

Here is the stack trace

这是堆栈跟踪

2017-09-04 09:20:02.476  INFO 18128 --- [           main] com.vir.VirBackendApplication            : The following profiles are active: prod
2017-09-04 09:20:02.536  INFO 18128 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@1ebd319f: startup date [Mon Sep 04 09:20:02 EDT 2017]; root of context hierarchy
2017-09-04 09:20:03.479  INFO 18128 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'dataSource' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=com.vir.config.DataConfig$ProdPlaceHolderConfig; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/vir/config/DataConfig$ProdPlaceHolderConfig.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=com.vir.config.EncryptorConfig$ProdPlaceHolderConfig; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/vir/config/EncryptorConfig$ProdPlaceHolderConfig.class]]
2017-09-04 09:20:03.898  INFO 18128 --- [           main] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2017-09-04 09:20:04.112  INFO 18128 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$55ffc8cc] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-09-04 09:20:04.421  INFO 18128 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 5000 (http)
2017-09-04 09:20:04.431  INFO 18128 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2017-09-04 09:20:04.432  INFO 18128 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.16
2017-09-04 09:20:04.589  INFO 18128 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2017-09-04 09:20:04.589  INFO 18128 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 2055 ms
2017-09-04 09:20:04.764  INFO 18128 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
2017-09-04 09:20:04.769  INFO 18128 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2017-09-04 09:20:04.769  INFO 18128 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2017-09-04 09:20:04.769  INFO 18128 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2017-09-04 09:20:04.769  INFO 18128 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2017-09-04 09:20:04.817  INFO 18128 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate Core {5.0.12.Final}
2017-09-04 09:20:04.820  INFO 18128 --- [           main] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found
2017-09-04 09:20:04.821  INFO 18128 --- [           main] org.hibernate.cfg.Environment            : HHH000021: Bytecode provider name : javassist
2017-09-04 09:20:04.967  WARN 18128 --- [           main] o.a.tomcat.jdbc.pool.PooledConnection    : Not loading a JDBC driver as driverClassName property is null.
2017-09-04 09:20:04.978 ERROR 18128 --- [           main] o.a.tomcat.jdbc.pool.ConnectionPool      : Unable to create initial connections of pool.

java.sql.SQLException: The url cannot be null
    at java.sql.DriverManager.getConnection(Unknown Source) ~[na:1.8.0_144]
    at java.sql.DriverManager.getConnection(Unknown Source) ~[na:1.8.0_144]
    at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:308) ~[tomcat-jdbc-8.5.16.jar:na]
    at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:203) ~[tomcat-jdbc-8.5.16.jar:na]
    at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:735) [tomcat-jdbc-8.5.16.jar:na]
    at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:667) [tomcat-jdbc-8.5.16.jar:na]
    at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:482) [tomcat-jdbc-8.5.16.jar:na]
    at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:154) [tomcat-jdbc-8.5.16.jar:na]
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:118) [tomcat-jdbc-8.5.16.jar:na]
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:107) [tomcat-jdbc-8.5.16.jar:na]
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:131) [tomcat-jdbc-8.5.16.jar:na]
    at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111) [spring-jdbc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77) [spring-jdbc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:326) [spring-jdbc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:366) [spring-jdbc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.boot.autoconfigure.orm.jpa.DatabaseLookup.getDatabase(DatabaseLookup.java:72) [spring-boot-autoconfigure-1.5.6.RELEASE.jar:1.5.6.RELEASE]
    at org.springframework.boot.autoconfigure.orm.jpa.JpaProperties.determineDatabase(JpaProperties.java:139) [spring-boot-autoconfigure-1.5.6.RELEASE.jar:1.5.6.RELEASE]
    at org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.jpaVendorAdapter(JpaBaseConfiguration.java:105) [spring-boot-autoconfigure-1.5.6.RELEASE.jar:1.5.6.RELEASE]
    at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration$$EnhancerBySpringCGLIB$$bf862cec.CGLIB$jpaVendorAdapter$9(<generated>) [spring-boot-autoconfigure-1.5.6.RELEASE.jar:1.5.6.RELEASE]
    at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration$$EnhancerBySpringCGLIB$$bf862cec$$FastClassBySpringCGLIB$$3d2e4b4f.invoke(<generated>) [spring-boot-autoconfigure-1.5.6.RELEASE.jar:1.5.6.RELEASE]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) [spring-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358) [spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration$$EnhancerBySpringCGLIB$$bf862cec.jpaVendorAdapter(<generated>) [spring-boot-autoconfigure-1.5.6.RELEASE.jar:1.5.6.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_144]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_144]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_144]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_144]

1 个解决方案

#1


0  

Ok so it took me a while but this is how I solved my issues; which turned out to be a few.

好的,我花了一段时间,但这就是我解决问题的方法;结果证明是少数。

  1. Make sure you include a property placeholder in the configuration so then the actual property value can bind to. Make sure to read about it here enter link description here
  2. 确保在配置中包含属性占位符,以便实际属性值可以绑定到该位置。请务必阅读此处,在此处输入链接说明

So now my application.yml file looks like bellow, and APP_ENCRYPTION_PASSWORD is an environment variable holding the encryption password.

所以现在我的application.yml文件看起来像下面,APP_ENCRYPTION_PASSWORD是一个包含加密密码的环境变量。

spring:
  profiles:
    active: prod
  output:
    ansi:
      enabled: detect
---
spring:
  profiles: dev
  application:
    name: App-Dev
  datasource:
    url: jdbc:mysql://localhost:3306/database?useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver 
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL5Dialect
server:
  port: 8080

---

spring:
  profiles: prod
  application:
    name: App-Prod
  datasource:
    url: jdbc:mysql://localhost:3306/database?useSSL=false
    username: root
    password: ENC(/98CfxmsjKBW5oZsLkLlmw==)
    driver-class-name: com.mysql.jdbc.Driver 
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: none
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL5Dialect
jasypt:
  encryptor:
    algorithm: PBEWithMD5AndDES
    password: ${APP_ENCRYPTION_PASSWORD}
server:
  port: 3000
  1. Only one data source configuration bean needed. I have it set to change active profiles so the correct configuration is picked.
  2. 只需要一个数据源配置bean。我已将其设置为更改活动配置文件,以便选择正确的配置。

Also create private variables and bind them with a @Value() annotation. Also add the @EnableEncryptableProperties to the class.

还要创建私有变量并使用@Value()注释绑定它们。还要将@EnableEncryptableProperties添加到类中。

DataConfig.java

@Configuration
@EnableEncryptableProperties
public class DataConfig {

    @Value("${spring.datasource.username}")
    private String userName;

    @Value("${spring.datasource.password}")
    private String password;

    @Value("${spring.datasource.url}")
    private String url;

    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;


    @Bean
    DataSource dataSource() {
        return DataSourceBuilder
                .create()
                .username(userName)
                .password(password)
                .url(url)
                .driverClassName(driverClassName)
                .build();
    }
}

And that's it it solved all my problems.

就是它解决了我所有的问题。

#1


0  

Ok so it took me a while but this is how I solved my issues; which turned out to be a few.

好的,我花了一段时间,但这就是我解决问题的方法;结果证明是少数。

  1. Make sure you include a property placeholder in the configuration so then the actual property value can bind to. Make sure to read about it here enter link description here
  2. 确保在配置中包含属性占位符,以便实际属性值可以绑定到该位置。请务必阅读此处,在此处输入链接说明

So now my application.yml file looks like bellow, and APP_ENCRYPTION_PASSWORD is an environment variable holding the encryption password.

所以现在我的application.yml文件看起来像下面,APP_ENCRYPTION_PASSWORD是一个包含加密密码的环境变量。

spring:
  profiles:
    active: prod
  output:
    ansi:
      enabled: detect
---
spring:
  profiles: dev
  application:
    name: App-Dev
  datasource:
    url: jdbc:mysql://localhost:3306/database?useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver 
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL5Dialect
server:
  port: 8080

---

spring:
  profiles: prod
  application:
    name: App-Prod
  datasource:
    url: jdbc:mysql://localhost:3306/database?useSSL=false
    username: root
    password: ENC(/98CfxmsjKBW5oZsLkLlmw==)
    driver-class-name: com.mysql.jdbc.Driver 
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: none
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL5Dialect
jasypt:
  encryptor:
    algorithm: PBEWithMD5AndDES
    password: ${APP_ENCRYPTION_PASSWORD}
server:
  port: 3000
  1. Only one data source configuration bean needed. I have it set to change active profiles so the correct configuration is picked.
  2. 只需要一个数据源配置bean。我已将其设置为更改活动配置文件,以便选择正确的配置。

Also create private variables and bind them with a @Value() annotation. Also add the @EnableEncryptableProperties to the class.

还要创建私有变量并使用@Value()注释绑定它们。还要将@EnableEncryptableProperties添加到类中。

DataConfig.java

@Configuration
@EnableEncryptableProperties
public class DataConfig {

    @Value("${spring.datasource.username}")
    private String userName;

    @Value("${spring.datasource.password}")
    private String password;

    @Value("${spring.datasource.url}")
    private String url;

    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;


    @Bean
    DataSource dataSource() {
        return DataSourceBuilder
                .create()
                .username(userName)
                .password(password)
                .url(url)
                .driverClassName(driverClassName)
                .build();
    }
}

And that's it it solved all my problems.

就是它解决了我所有的问题。