Kapil Choubisa
Kapil Choubisa

Reputation: 5232

ConfigurationProperties with prefix is not working

I am very new in spring boot and creating my first application. While creating data source I am using @ConfigurationProperties with prefix and properties to be read from application.property.

However, this setup doesn't seems to work for me and my program is not running.

My properties from application.property file:

spring.datasource.url=jdbc:h2:file:~/appboot
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver

My Code:

@Configuration
public class PersistentConfiguration {

    @Bean
    @ConfigurationProperties(prefix="spring.datasource")
    @Primary
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }
}

I understand that @ConfigurationProperties is not reading the properties from my file. If I provide details in builder method as below, it works well:

return DataSourceBuilder.create()
.url("jdbc:h2:file:~/appboot")
.username("sa")
.password("")
.driverClassName("org.h2.Driver")
.build();

My pom.xml file has:

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

My Repository class:

import org.springframework.data.jpa.repository.JpaRepository;

import com.boot.model.Shipwreck;

public interface ShipwreckRepository extends JpaRepository<Shipwreck, Long>{

}

My Main class:

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

error:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1699) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:573) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:304) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE] at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1089) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:859) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:780) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:333) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1277) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1265) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE] at com.boot.App.main(App.java:15) [classes/:na] Caused by: java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName. at com.zaxxer.hikari.HikariConfig.validate(HikariConfig.java:1059) ~[HikariCP-2.7.9.jar:na] at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:109) ~[HikariCP-2.7.9.jar:na] at org.flywaydb.core.internal.util.jdbc.JdbcUtils.openConnection(JdbcUtils.java:51) ~[flyway-core-5.0.7.jar:na] at org.flywaydb.core.internal.database.DatabaseFactory.createDatabase(DatabaseFactory.java:67) ~[flyway-core-5.0.7.jar:na] at org.flywaydb.core.Flyway.execute(Flyway.java:1634) ~[flyway-core-5.0.7.jar:na] at org.flywaydb.core.Flyway.migrate(Flyway.java:1168) ~[flyway-core-5.0.7.jar:na] at org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializer.afterPropertiesSet(FlywayMigrationInitializer.java:66) ~[spring-boot-autoconfigure-2.0.5.RELEASE.jar:2.0.5.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1758) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1695) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE] ... 18 common frames omitted

Please let me know if I need to provide any other information as well.

Upvotes: 1

Views: 4339

Answers (2)

JUAN CALVOPINA M
JUAN CALVOPINA M

Reputation: 3965

Spring Boot give us many facilities to create applications, for example if you want to use the database H2, you only need to add the dependency to your pom file and add the respective properties in the application.properties file, there are some default properties that allow transparent communication between the database and the application, as for example:

# To save the db in memory
#spring.datasource.url=jdbc:h2:mem:test

# To save the db in a file within the project
spring.datasource.url=jdbc:h2:./db/test
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.platform=h2

I mean DataSource configuration is controlled by external configuration properties in spring.datasource.*, so you don't need define PersistentConfiguration class, it is enough to correctly define those properties for the application works well. Make sure you have added dependency H2 in your pom.xml file:

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

Also you can check the data in the db:

http://<host>:<port>/<context-path>/h2-console/

For example:

http://localhost:8080/my-first-app/h2-console

Upvotes: 1

Molay
Molay

Reputation: 1404

Check if this helps:

import java.util.Map;

import javax.sql.DataSource;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConfigurationProperties
public class PersistentConfiguration {

  Map<String, String> datasource;

  public DataSource getDatasources() {
    System.out.println("datasources ==="+datasource);
    return DataSourceBuilder.create()
        .url(datasource.get("url"))
        .username(datasource.get("username"))
        .password(datasource.get("password"))
        .driverClassName(datasource.get("driver-class-name"))
        .build();
  }

  public void setDatasource(Map<String, String> datasource) {
    this.datasource = datasource;
  }
}

application.properties file:

datasource[url]=jdbc:mysql://localhost:3000/andatabase?useSSL=false
datasource[username]=root
datasource[password]=password
datasource[driver-class-name]=com.mysql.jdbc.Driver

In Controller:

@Autowired
PersistentConfiguration config;

@GetMapping("/language")
public ResponseEntity control() {

config.getDatasources();

return new ResponseEntity("success", HttpStatus.OK);
}

Upvotes: 1

Related Questions