code-geek
code-geek

Reputation: 463

Spring Boot - Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured

I want to configure two datasources in my SpringBoot (version 2.4) application.

Below is the application.properties:

spring.datasource2.url=jdbc:postgresql://localhost:5432/db1
spring.datasource2.username=//username
spring.datasource2.password=//pwd
spring.datasource2.initialization-mode=always
spring.datasource2.driver-class-name=org.postgresql.Driver

spring.datasource1.url=jdbc:postgresql://localhost:5432/db2
spring.datasource1.username=//usrename
spring.datasource1.password=//pwd
spring.datasource1.initialization-mode=always
spring.datasource1.driver-class-name=org.postgresql.Driver

spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false
spring.jpa.hibernate.show-sql=true
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

spring.jpa.hibernate.ddl-auto=none
spring.jpa.properties.hibernate.id.new_generator_mappings=false
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

spring.h2.console.enabled=true
spring.datasource.continue-on-error=true

spring.servlet.multipart.max-file-size=50MB

spring.servlet.multipart.max-request-size=50MB


project.http.enable=false
project.https.port=9090

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration

server.os=LINUX

dl.writeTOFile=false
dl.writeTOConsole=true

Below is my pom.xml:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</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-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </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-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <!-- marked the embedded servlet container as provided -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-batch</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
            <version>2.4.0</version>
        </dependency>

When I run the application, I get the following error:

***************************
APPLICATION FAILED TO START
***************************

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).

When I add one datasource as Spring.datasource and other as Spring.datasource1, application starts up fine but it is looking into the DB configured in Spring.datasource only.

Following is the DB1 Config class:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories( entityManagerFactoryRef = "DB1EntityManagerFactory", transactionManagerRef = "DB1TransactionManager",    basePackages = {
    "com.datasource1.repository" } )
@EntityScan("com.datasource1.entity" )
public class Db1Config {
    
        @Primary
        @Bean
        @ConfigurationProperties("spring.datasource")
        public DataSourceProperties SourceProperties() {
            return new DataSourceProperties();
        }
        
        @Primary
        @Bean( name = "DB1Datasource" )
        @ConfigurationProperties( prefix = "spring.datasource.configuration" )
        public DataSource dataSource()
        {
            return SourceProperties().initializeDataSourceBuilder()
                    .type(HikariDataSource.class).build();
        }
        
        @Primary
        @Bean( name = "DB1EntityManagerFactory" )
        public LocalContainerEntityManagerFactoryBean barEntityManagerFactory( EntityManagerFactoryBuilder builder,
                @Qualifier( "DB1Datasource" ) DataSource dataSource )
        {
            return builder.dataSource(dataSource).packages("com.datasource1.entity")
                    .persistenceUnit("db1").build();
        }
        
        @Primary
        @Bean( name = "DB1TransactionManager" )
        public PlatformTransactionManager barTransactionManager(
                @Qualifier( "DB1EntityManagerFactory" ) EntityManagerFactory barEntityManagerFactory )
        {
            return new JpaTransactionManager(barEntityManagerFactory);
        }
}

Following is the DB2Config:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories( entityManagerFactoryRef = "DB2EntityManagerFactory", transactionManagerRef = "DB2TransactionManager",    basePackages = {
    "com.DB2.repository" } )
@EntityScan( "com.DB2.entity" )
public class Db2Config {
    
        @Bean
        @ConfigurationProperties("spring.datasource2")
        public DataSourceProperties DB2SourceProperties() {
            return new DataSourceProperties();
        }

        
        @Bean( name = "DB2Datasource" )
        @ConfigurationProperties( prefix = "spring.datasource2.configuration" )
        public DataSource dataSource()
        {
            return DB2SourceProperties().initializeDataSourceBuilder()
                    .type(HikariDataSource.class).build();
        }
        
        @Bean( name = "DB2EntityManagerFactory" )
        public LocalContainerEntityManagerFactoryBean barEntityManagerFactory( EntityManagerFactoryBuilder builder,
                @Qualifier( "DB2Datasource" ) DataSource dataSource )
        {
            return builder.dataSource(dataSource).packages("com.DB2.entity")
                    .persistenceUnit("db2").build();
        }
        
        @Bean( name = "DB2TransactionManager" )
        public PlatformTransactionManager barTransactionManager(
                @Qualifier( "DB2EntityManagerFactory" ) EntityManagerFactory barEntityManagerFactory )
        {
            return new JpaTransactionManager(barEntityManagerFactory);
        }
}

How do I resolve this issue?

Upvotes: 5

Views: 30388

Answers (3)

You get this error when you have more than one configuration/properties file in the resources folder. For example, if you have application.properties, configuration.yml files

Then you have to tell Spring to use both the files for properties or configuration. By default, spring detects or makes use of only the application.properties file.

In the main class, you can define like this:

System.setProperty("spring.config.additional-location", "classpath:configuration.yml");

Similary add all your configuration/properties files to System. It works!

Upvotes: 0

sifr_dot_in
sifr_dot_in

Reputation: 3623

i faced this issue after creating "project.jar" while in IDE / STS (spring tool suit) it was working fine.

unnecessary spaces " " in the "application.yml" file can cause this.

server:
  port: 8085


spring:
 datasource:
  url: jdbc:mysql://localhost:3306/studentdb
  username: root
  password: root
  driver-class-name: com.mysql.cj.jdbc.Driver
 jpa:
   hibernate:
    ddl-auto: update
   show-sql: true
   database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
 application:
  name: STUDENT-SERVICE

instead of tweaking my "application.yml" file
i simply moved all my statements in "application.yml" file to
"application.properties" file and formatted the statements like required in ".properties".

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/studentdb
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format.sql=true

spring.application.name=student-service

server.port=8085

(you can add params at the end of url)
(spring.datasource.url=jdbc:mysql://localhost:3306/studentdb?allowPublicKeyRetrieval=true&useSSL=false)

and voilà

Upvotes: 1

Amir Schnell
Amir Schnell

Reputation: 651

You should change

spring.datasource1.url=jdbc:postgresql://localhost:5432/db2

to

spring.datasource1.jdbc-url=jdbc:postgresql://localhost:5432/db2

Not sure why this is the case and the docs don't say so, but I had this issue and this did the trick for me

Edit: As @M. Deinum mentioned in his comment: These

        @ConfigurationProperties("spring.datasource")
        (...)
        @ConfigurationProperties( prefix = "spring.datasource.configuration" )

should be changed to

        @ConfigurationProperties("spring.datasource1")
        (...)
        @ConfigurationProperties( prefix = "spring.datasource1.configuration" )

Upvotes: 3

Related Questions