skip to Main Content

I have a springboot 3 application, pretty standard, which has a Controller, a service that is called by the controller and a repository that the service uses to fetch and save data.

I had configured my application to work with a postgresql DB, and it was actually working quite well. Then I decided to do some refactoring (originally, all logic was in the controller, I introduced the service mentioned above and moved it there). I didn’t change anything to the Application launcher, the application.properties or anything else.

Now when I try to start 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).

While the actual runtimeException where my debug point occurs says:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘dataSourceScriptDatabaseInitializer’ defined in class path resource [org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class]: Unsatisfied dependency expressed through method ‘dataSourceScriptDatabaseInitializer’ parameter 0: Error creating bean with name ‘dataSource’ defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method ‘dataSource’ threw exception with message: Failed to determine a suitable driver class

I found some threads saying to (exclude = DataSourceAutoConfiguration.class) to my SpringBootApplication annotation, but this just results in another error saying UnsatisfiedDependencyException where my Repository is not available for injection into my controller.

I’ve tried undoing all of my refactoring but still it’s not working, and I’m quite stuck on this.

Application:
Application

Repository:
Repository

Controller:
Controller

Service:
Service

Application.properties:
Properties

pom.xml:
Pom

Tried excluding DataSourceAutoConfiguration from the SpringBootApplication annotation, but this resulted in the TranslationRepository not being available in my TranslationService.
Tried reverting my changes but that didn’t help.
Tried adding explicit postgres driver property to application.properties, also didn’t help.

As suggested by Mox:

TranslationApplication:

package com.projectbluegames.tbd;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class TranslationApplication {

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

}

properties:

spring.datasource.url=jdbc:postgresql://localhost:5432/TBD
spring.datasource.username=postgres
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.datasource.driver-class-name=org.postgresql.Driver

Repository:

package com.projectbluegames.tbd.repository;

import org.springframework.data.repository.CrudRepository;

import com.projectbluegames.tbd.entities.Translation;

public interface TranslationRepository extends CrudRepository<Translation, Integer> {}
    

Controller:

@RestController
public class TranslationController {

    private final ITranslationService translationService;
    
    public TranslationController(ITranslationService translationService) {
        this.translationService = translationService;
    }

    @PostMapping("/refresh")
    private ResponseEntity<String> refreshTranslationCache() {
        translationService.refreshTranslationCache();
        return ResponseEntity.ok("Translation cache reloaded successfully");
    }
}

IService:

package com.projectbluegames.tbd.services;

import java.util.List;

import com.projectbluegames.tbd.dtos.TranslationDto;

public interface ITranslationService {
    
    public void refreshTranslationCache();
    
}

Service:

package com.projectbluegames.tbd.services;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.projectbluegames.tbd.entities.Translation;
import com.projectbluegames.tbd.repository.TranslationRepository;

public class TranslationService implements ITranslationService {
    
    private final TranslationRepository translationRepository;
    
    private Map<String, Translation> translationCache = new HashMap<String, Translation>();

    public TranslationService(TranslationRepository translationRepository) {
        this.translationRepository = translationRepository;
        refreshTranslationCache();
    }
    
    @Override
    public void refreshTranslationCache() {
        translationCache.clear();
        Iterable<Translation> translations = translationRepository.findAll();
        translations.forEach(t -> translationCache.put(t.getLanguage() + "_" + t.getKey(), t));
    }
}

Translation Entity:

package com.projectbluegames.tbd.entities;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;

@Entity
@Table(name="translations")
public class Translation {
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    
    private String key;
    
    private String language;
    private String value;
    
    private Translation() { }
    
    public Translation(String key, String language, String value) {
        this.key = key;
        this.language = language;
        this.value = value;
    }
    
    public String getKey() {
        return key;
    }
    
    public String getLanguage() {
        return language;
    }
    
    public String getValue() {
        return value;
    }
    
    public void setValue(String value) {
        this.value = value;
    }
    
}

pom:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.pb</groupId>
    <artifactId>core</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>tbd</name>
    <description>Core</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</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-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
          
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    
</project>

2

Answers


  1. Chosen as BEST ANSWER

    As part of my refactoring, I had added to the pom.xml

    <packaging>pom</packaging>
    

    Which I had forgotten to remove.

    After removing this, it works.


  2. Include the following property in your properties file

    spring.datasource.driver-class-name=org.postgresql.Driver
    

    This should mostly resolve.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search