I have a problem when launching the application :
Description:
Parameter 0 of constructor in com.backend.services.RoleService required a bean of type 'com.backend.repository.RoleRepository' that could not be found.
Action:
Consider defining a bean of type 'com.backend.repository.RoleRepository' in your configuration.
Has anyone experienced this problem?
Project structure:
com.backend
entity.Role
enums.ERole
repository.RoleRepository
services.RoleService
Its code
Application.yml (dev I using it)
spring:
config:
activate:
on-profile: "dev"
datasource:
url: jdbc:mysql://localhost:3306/${MYSQL_DATABASE}
username: ${MYSQL_USER}
password: ${MYSQL_PASSWORD}
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: create
show-sql: true
properties:
hibernate:
dialect: "org.hibernate.dialect.MySQL5InnoDBDialect"
flyway:
enabled: true
url: jdbc:mysql://localhost:3306/${MYSQL_DATABASE}
locations: classpath:db/migration
user: ${MYSQL_USER}
password: ${MYSQL_PASSWORD}
create-schemas: true
default-schema: ${MYSQL_DATABASE}
#logging:
# level:
# root: debug
jwtSecret: "superkode"
jwtExpirationMs: 86400000
jwtRefreshExpirationMs: 120000
Entity:
package com.backend.entity;
import com.backend.enums.ERole;
import jakarta.persistence.*;
import lombok.*;
import java.math.BigInteger;
@Entity
@Table(name = "roles")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(length = 20, nullable = false)
private ERole name;
}
Enum:
package com.backend.enums;
public enum ERole {
USER,
BUSINESS,
ADMIN
}
Service:
package com.backend.services;
import com.backend.entity.Role;
import com.backend.enums.ERole;
import com.backend.repository.RoleRepository;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Service
public class RoleService {
private final RoleRepository roleRepository;
public RoleService(RoleRepository roleRepository) {
this.roleRepository = roleRepository;
}
public Optional<Role> findByName(ERole name) {
return roleRepository.findByName(name);
}
}
Repository:
package com.backend.repository;
import com.backend.entity.Role;
import com.backend.enums.ERole;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface RoleRepository extends JpaRepository<Role, Long> {
Optional<Role> findByName(ERole name);
}
What I tried:
Add @Autowired, and I get an error like this
Add package scanning anotation to BackendApplication, and I get a similar error
I use gradlew:
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.5'
id 'io.spring.dependency-management' version '1.1.3'
id 'org.asciidoctor.jvm.convert' version '3.3.2'
}
group = 'com.backend'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
ext {
set('snippetsDir', file("build/generated-snippets"))
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-r2dbc'
implementation 'org.springframework.boot:spring-boot-starter-data-rest'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'me.paulschwarz:spring-dotenv:4.0.0'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-validation:3.1.5'
implementation 'org.mapstruct:mapstruct-processor:1.6.0.Beta1'
implementation 'org.mapstruct:mapstruct:1.6.0.Beta1'
implementation 'com.auth0:java-jwt:4.4.0'
implementation 'io.jsonwebtoken:jjwt:0.12.3'
implementation 'io.jsonwebtoken:jjwt-api:0.12.3'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.3'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.3'
implementation 'org.flywaydb:flyway-core'
runtimeOnly 'org.flywaydb:flyway-mysql'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.h2database:h2'
runtimeOnly 'com.mysql:mysql-connector-j'
runtimeOnly 'io.asyncer:r2dbc-mysql'
runtimeOnly 'io.r2dbc:r2dbc-h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
testImplementation 'org.springframework.security:spring-security-test'
}
tasks.named('test') {
outputs.dir snippetsDir
useJUnitPlatform()
}
tasks.named('asciidoctor') {
inputs.dir snippetsDir
dependsOn test
}
And Application file:
package com.backend;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@SpringBootApplication
public class BackendApplication {
public static void main(String[] args) {
SpringApplication.run(BackendApplication.class, args);
}
}
[SOLVED] I refactored gradlew, removed conflicting dependencies with DB:
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.5'
id 'io.spring.dependency-management' version '1.1.3'
}
group = 'com.backend'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web:3.1.5'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa:3.1.5'
implementation 'org.springframework.boot:spring-boot-starter-security:3.1.5'
implementation 'org.springframework.boot:spring-boot-starter-validation:3.1.5'
implementation 'com.mysql:mysql-connector-j:8.2.0'
implementation 'com.auth0:java-jwt:4.4.0'
implementation 'io.jsonwebtoken:jjwt-api:0.12.3'
implementation 'me.paulschwarz:spring-dotenv:4.0.0'
implementation 'org.flywaydb:flyway-core:10.0.0'
implementation 'org.flywaydb:flyway-mysql:10.0.0'
compileOnly 'org.projectlombok:lombok:1.18.30'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.3'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.3'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
}
tasks.named('test') {
useJUnitPlatform()
}
Okay so the entire problem is that Spring is not able to decide how to create your Repository class, since you are having multiple starter-data
projects implemented in your project. That is, you are using MySQL as your vendor, and for using an ORM with MySQL only JPA would suffice, but for any reasons like you want to write clear queries you may want to add JDBC as well, but removing R2DBC implementation and the unwanted Drivers from the dependencies cleared out your problem.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-rest'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'me.paulschwarz:spring-dotenv:4.0.0'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-validation:3.1.5'
implementation 'org.mapstruct:mapstruct-processor:1.6.0.Beta1'
implementation 'org.mapstruct:mapstruct:1.6.0.Beta1'
implementation 'com.auth0:java-jwt:4.4.0'
implementation 'io.jsonwebtoken:jjwt:0.12.3'
implementation 'io.jsonwebtoken:jjwt-api:0.12.3'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.3'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.3'
implementation 'org.flywaydb:flyway-core'
runtimeOnly 'org.flywaydb:flyway-mysql'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
testImplementation 'org.springframework.security:spring-security-test'}
this will run your project
and one more thing, I am not sure if Spring provides engine specific Dialects, but 5InnoDB Dialect is definitely not gonna work, you might want to implement an engine specific Driver then, else you could simply use MySQLDialect
and your project would start running, without any problem.
The issue was with Spring not knowing in which flavor it should create your repository class. And therefore left it uncreated, which later reflected in a bean not found exception.
Hope you understood the problem.