0
votes

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.

2
How are you accessing the database? Repository , DataSource , JdbcTemplate ? If, for example, you use Spring Data JPA Repositories you don't need anything except the properties.Boris
I think I am using it through JPA repository only. spring-boot-starter-data-jpa is added in my pom.xml and I edited my question with my repository class. It is empty as of now.Kapil Choubisa
Can you add the corresponding code to avoid any assumptions?Boris

2 Answers

0
votes

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);
}
0
votes

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