0

In sandbox project trying reactive webflux with springboot and postgres. I added r2dbc, created endpoints - get all records and post endpoints work, but appeared problem with requests which use path variable (get one record, or delete by id) Here is my code:

@SpringBootApplication
@EnableR2dbcAuditing
public class Springboot2Application {
    public static void main(String[] args) {
        SpringApplication.run(Springboot2Application.class, args);
    }
}

Controller:

@RequiredArgsConstructor
@RestController
@RequestMapping("/api/v1")
public class ToDoController {
    private final ToDoRepository repository;

    @GetMapping(value = "/to-do/{toDoId}", produces = {
            MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE})
    public Mono<ResponseEntity<ToDo>> getToDo(@Valid @PathVariable Long toDoId) {
        return repository.findById(toDoId)
                .map(ResponseEntity::ok);
    }
}

repository:

@Repository
public interface ToDoRepository extends R2dbcRepository<ToDo,Long> {
}

entity:

@Data
@RequiredArgsConstructor
@Table(name = "to_do")
public class ToDo {
    @Id
    private Long id;
    @Version
    private Long version;
    @NotNull
    @NotBlank
    private String description;
    @CreatedDate
    private Timestamp created;
    @LastModifiedDate
    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());
    }

    @Bean
    ReactiveTransactionManager transactionManager(ConnectionFactory connectionFactory) {
        return new R2dbcTransactionManager(connectionFactory);
    }
}

And my 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>
    </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>

table creation sql:

CREATE TABLE to_do
(
    ID          SERIAL primary key ,
    version     bigint,
    description char(255),
    created     timestamp,
    modified    timestamp,
    completed   boolean
);

So when I execute GET http://localhost:8080/api/v1/to-do/3 I get:

java.lang.IllegalStateException: Required identifier property not found for class com.springboot2.domain.ToDo

I tried to define this using @Query in repository, but got same result. I suppose problem can be either in my table, or in entity, but I can't see it. And also seems @Version does not work(every time writes null to table)

Sam Fisher
  • 746
  • 2
  • 10
  • 27

2 Answers2

1

The problem may be in wrong import of @Id annotation in your domain.

It should be from package

org.springframework.data.annotation.Id

But in your case it is from package

javax.persistence

Also, consider the naming of fields. As in your domain id is declared as "id", I can see in your create script id as "ID" (in uppercase).

kerbermeister
  • 2,985
  • 3
  • 11
  • 30
0

You can use an Entity in rd2bc without @id. Or use it in the correct’s package name.