Have sandbox springboot app. Decided to try reactive approach, postgres
is used as database, I added r2dbc to the project to make my repository reactive. Here is my code:
@SpringBootApplication
public class Springboot2Application {
public static void main(String[] args) {
SpringApplication.run(Springboot2Application.class, args);
}
}
@Repository
public interface ToDoRepository extends
ReactiveCrudRepository<ToDo,String> {
}
@RestController
@RequestMapping("/api/v1")
public class ToDoController {
private final ToDoRepository repository;
public ToDoController(ToDoRepository repository) {
this.repository = repository;
}
@GetMapping(value = "/to-do", produces = {
MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_XML_VALUE,
MediaType.TEXT_XML_VALUE})
public ResponseEntity<Flux<ToDo>> getToDos(@RequestHeader
HttpHeaders headers){
return ResponseEntity.ok().body(repository.findAll());
}
}
@Data
@RequiredArgsConstructor
@Entity
@Table(name = "todo")
public class ToDo {
@Id
@NotNull
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
private String id;
@NotNull
@NotBlank
private String description;
@CreationTimestamp
private Timestamp created;
@UpdateTimestamp
private Timestamp modified;
private boolean completed;
}
r2dbc config:
@Configuration
@EnableR2dbcRepositories(basePackages =
"com.springboot2.repository")
public class R2DBCConfig extends AbstractR2dbcConfiguration {
@Bean
public ConnectionFactory connectionFactory() {
return ConnectionFactories.get(
ConnectionFactoryOptions.builder()
.option(DRIVER, "postgresql")
.option(HOST, "localhost")
.option(PORT, 5432)
.option(USER, "admin")
.option(PASSWORD, "admin")
.option(DATABASE, "springdb")
.build());
}
}
On application start I'm getting:
Description:
Parameter 0 of constructor in com.springboot2.controller.ToDoController required a bean of type 'com.springboot2.repository.ToDoRepository' that could not be found.
Action:
Consider defining a bean of type 'com.springboot2.repository.ToDoRepository' in your configuration.
I tried to add @ComponentsScan
, tried to move ToDoRepository
to the root near Springboot2Application
, I dont understand why Spring doesn't see repository interface
pom.file:
<?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>2.7.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.springboot</groupId>
<artifactId>springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot2</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>8</java.version>
<spring-cloud.version>2021.0.3</spring-cloud.version>
<!-- <spring-shell.version>2.1.0</spring-shell.version>-->
</properties>
<dependencies>
<!-- DB,ORM, and plugins-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</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-data-r2dbc</artifactId>
</dependency>
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-postgresql</artifactId>
<version>0.8.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!-- Reactive libs-->
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
My guess the reason is that you have added r2dbc driver to your project, but haven't added spring-boot-starter-data-r2dbc
So, consider this dependency in your pom.xml
file (this is the latest version at the time of writing this answer) :
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-r2dbc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
<version>3.0.2</version>
</dependency>
EDIT:
Also you can try to use @EnableR2dbcRepositories
and specify the package with your repository.
One more possible way to solve this is to extend your repository from R2dbcRepository
, instead of ReactiveCrudRepository
This may help when you have multiple spring data reactive modules (r2dbc and something else) being used in the same project. Since ReactiveCrudRepository
is a generic interface Spring does not know how to properly configure these beans.