Ошибка при получении записей по id с помощью r2dbc

В проекте песочницы пробуем реактивный webflux с springboot и postgres. Добавил r2dbc, создал эндпоинты - получить все записи и пост эндпоинты работают, но появилась проблема с запросами которые используют переменную пути (получить одну запись или удалить по id) Вот мой код:

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

Контроллер:

@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
public interface ToDoRepository extends R2dbcRepository<ToDo,Long> {
}

сущность:

@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:

@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);
    }
}

И мой файл 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>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>

создание таблицы sql:

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

Итак, когда я выполняю GET http://localhost:8080/api/v1/to-do/3, я получаю:

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

Я попытался определить это с помощью @Query в репозитории, но получил тот же результат. Я предполагаю, что проблема может быть либо в моей таблице, либо в сущности, но я ее не вижу. И тоже похоже @Version не работает(каждый раз пишет ноль в таблицу)

Из какого пакета аннотация @Id в вашем домене?

kerbermeister 07.02.2023 20:27

также я вижу, что у вас есть столбец идентификатора в базе данных в верхнем регистре.

kerbermeister 07.02.2023 21:23

Идентификатор @kerbermeister импортируется из javax.persistence. и вы правы - я меняю пакет импорта на org.springframework.data.annotation.Id и он работает! Вы можете написать это в ответ, я буду применять его?

Sam Fisher 08.02.2023 09:50

Я думаю, что он не распознает идентификатор, поскольку ожидает «id», а не «ID».

kerbermeister 08.02.2023 09:51

Проблема @kerbermeister в неправильном импорте. org.springframework.data.annotation.Id сделал свое дело. id в базе данных записывается строчными буквами (возможно, Intelij преобразовал его во время выполнения)

Sam Fisher 08.02.2023 09:52

@kerbermeister, не могли бы вы добавить эту информацию в ответ, и я ее одобрю?

Sam Fisher 08.02.2023 13:50
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
6
123
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема может заключаться в неправильном импорте аннотации @Id в ваш домен.

Это должно быть из пакета

org.springframework.data.annotation.Id

Но в вашем случае это из пакета

javax.persistence

Также подумайте об именовании полей. Поскольку в вашем домене идентификатор объявлен как «id», я вижу в вашем идентификаторе сценария создания как «ID» (в верхнем регистре).

Другие вопросы по теме