Проблема Webflux R2dbc с таблицами отношений один к одному

Привет всем, я пишу проект Rest API с R2dbc (неблокирующий), но проблема связана с отношением таблиц

Модель задачи

 @Getter
 @Setter
 @Entity(name = "task")
 @Table(name = "task")
 public class Task {

    @Id
    @Column(name = "id",unique = true,nullable = false)
    private Integer id;

    @Column(name = "comment_count")
    private Integer comment_count;

    @Column(name = "completed")
    private Boolean completed;

    @Column(name = "content")
    private String  content;

    @Column(name = "url")
    private String  url;

    @Column(name = "orderdata")
    private Integer orderdata;

    @Column(name = "priority")
    private Integer priority;

    @OneToOne
    @JoinColumn(name = "due_id")//this is relation table Due but this relation retunr response null
    private Due due;

 }

Подходящая модель

  @Getter
  @Setter//Lombok library
  @Entity
  @Table(name = "due")
  public class Due {

    @Id
    @Column(nullable = false, unique = true, updatable = false)
    private Integer id;

   @Column(name = "date_data")
   private Date date_Data;

   @Column
   private Boolean recurring;

   @Column(name = "string_data")
  private String string_data;


}

Репозиторий задач//это реактивный репозиторий crud

     @Repository
     public interface TasksRepository extends ReactiveCrudRepository<Task,Integer> {

      }

Диспетчер задач//это бизнес-уровень

   @Component
   @Slf4j
   @RequiredArgsConstructor
   public class  TaskManager {

          private final TasksRepository tasksRepository;

          public Flux<Task> findAll() {
           return tasksRepository.findAll();
          }

      }

Служба задач//это сервисный уровень

    @Service
    @RequiredArgsConstructor
    public class TasksService {


        private final TaskManager taskManager;


          public Flux<Task> getAll() {
            return taskManager.findAll();
      }
    }

Контроллер задач

  @RestController
  @RequestMapping("/api/tasks")
  @RequiredArgsConstructor
  public class TasksController {


        private final TasksService tasksService;

         @GetMapping
         public Flux<Task> getAllTasks(){
          return tasksService.getAll();
       }
     }

Задача Ответ

Моя задача ответа Rest Api

     {
        "id": 1,
        "comment_count": 10,
        "completed": false,
        "content": "new content",
        "url": "http:8085.com",
        "orderdata": 5,
        "priority": 5,
        "due": {
             "id": 3,
             "date_Data": null,
             "recurring": null,
             "string_data": null
 
      } 

Проблема Отношение один к одному Ответ null В чем проблема??? Пожалуйста, помогите мне Спасибо

Трассировка ошибок

  2021-03-20 20:49:57.161 ERROR 13652 --- [actor-tcp-nio-1] 
   r.n.channel.ChannelOperationsHandler     : [id: 0x1126662b, 
    L:/127.0.0.1:55827 - R:localhost/127.0.0.1:5432] Error was received while 
     reading the incoming data. The connection will be closed.

    java.lang.StackOverflowError: null
      at  io.netty.util.internal.ReferenceCountUpdater
     .isLiveNonVolatile(ReferenceCountUpdt 
     er.java:88) ~[netty-common-4.1.59.Final.jar:4.1.59.Final]
         at 
      io.netty.buffer.AbstractReferenceCountedByteBuf
      .isAccessible(AbstractReferenceCountedByteBuf.java:56) ~[netty-buffer- 
       4.1.59.Final.jar:4.1.59.Final]
       at io.netty.buffer.AbstractByteBuf.ensureAccessible(AbstractByteBuf.java:1455) ~[netty-buffer-4.1.59.Final.jar:4.1.59.Final]
at io.netty.buffer.AbstractByteBuf.checkIndex(AbstractByteBuf.java:1385) ~[netty-buffer-4.1.59.Final.jar:4.1.59.Final]
at io.netty.buffer.UnsafeByteBufUtil.getBytes(UnsafeByteBufUtil.java:481) ~[netty-buffer-4.1.59.Final.jar:4.1.59.Final]
at io.netty.buffer.PooledUnsafeDirectByteBuf.getBytes(PooledUnsafeDirectByteBuf.java:130) ~[netty-buffer-4.1.59.Final.jar:4.1.59.Final]
at io.netty.buffer.PooledSlicedByteBuf.getBytes(PooledSlicedByteBuf.java:235) ~[netty-buffer-4.1.59.Final.jar:4.1.59.Final]
at io.netty.buffer.ByteBufUtil.decodeString(ByteBufUtil.java:1147) ~[netty-buffer-4.1.59.Final.jar:4.1.59.Final]
at io.netty.buffer.AbstractByteBuf.toString(AbstractByteBuf.java:1248) ~[netty-buffer-4.1.59.Final.jar:4.1.59.Final]
at io.netty.buffer.AbstractByteBuf.getCharSequence(AbstractByteBuf.java:515) ~[netty-buffer-4.1.59.Final.jar:4.1.59.Final]
at io.netty.buffer.AbstractByteBuf.readCharSequence(AbstractByteBuf.java:520) ~[netty-buffer-4.1.59.Final.jar:4.1.59.Final]
at io.r2dbc.postgresql.util.ByteBufUtils.decode(ByteBufUtils.java:42) ~[r2dbc-postgresql-0.8.6.RELEASE.jar:0.8.6.RELEASE]
at io.r2dbc.postgresql.codec.AbstractNumericCodec.decodeNumber(AbstractNumericCodec.java:122) ~[r2dbc-postgresql-0.8.6.RELEASE.jar:0.8.6.RELEASE]
at io.r2dbc.postgresql.codec.AbstractNumericCodec.decodeNumber(AbstractNumericCodec.java:89) ~[r2dbc-postgresql-0.8.6.RELEASE.jar:0.8.6.RELEASE]
at io.r2dbc.postgresql.codec.IntegerCodec.doDecode(IntegerCodec.java:49) ~[r2dbc-postgresql-0.8.6.RELEASE.jar:0.8.6.RELEASE]
at io.r2dbc.postgresql.codec.IntegerCodec.doDecode(IntegerCodec.java:30) ~[r2dbc-postgresql-0.8.6.RELEASE.jar:0.8.6.RELEASE]
at io.r2dbc.postgresql.codec.AbstractCodec.decode(AbstractCodec.java:82) ~[r2dbc-postgresql-0.8.6.RELEASE.jar:0.8.6.RELEASE]
at io.r2dbc.postgresql.codec.DefaultCodecs.decode(DefaultCodecs.java:149) ~[r2dbc-postgresql-0.8.6.RELEASE.jar:0.8.6.RELEASE]
at io.r2dbc.postgresql.PostgresqlRow.decode(PostgresqlRow.java:90) ~[r2dbc-postgresql-0.8.6.RELEASE.jar:0.8.6.RELEASE]
at io.r2dbc.postgresql.PostgresqlRow.get(PostgresqlRow.java:77) ~[r2dbc-postgresql-0.8.6.RELEASE.jar:0.8.6.RELEASE]
at io.r2dbc.spi.Row.get(Row.java:76) ~[r2dbc-spi-0.8.3.RELEASE.jar:na]
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readFrom(MappingR2dbcConverter.java:173) ~[spring-data-r2dbc-1.2.5.jar:1.2.5]
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readEntityFrom(MappingR2dbcConverter.java:294) ~[spring-data-r2dbc-1.2.5.jar:1.2.5]
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readFrom(MappingR2dbcConverter.java:166) ~[spring-data-r2dbc-1.2.5.jar:1.2.5]
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readEntityFrom(MappingR2dbcConverter.java:294) ~[spring-data-r2dbc-1.2.5.jar:1.2.5]
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readFrom(MappingR2dbcConverter.java:166) ~[spring-data-r2dbc-1.2.5.jar:1.2.5]
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readEntityFrom(MappingR2dbcConverter.java:294) ~[spring-data-r2dbc-1.2.5.jar:1.2.5]
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readFrom(MappingR2dbcConverter.java:166) ~[spring-data-r2dbc-1.2.5.jar:1.2.5]
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readEntityFrom(MappingR2dbcConverter.java:294) ~[spring-data-r2dbc-1.2.5.jar:1.2.5]
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readFrom(MappingR2dbcConverter.java:166) ~[spring-data-r2dbc-1.2.5.jar:1.2.5]
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readEntityFrom(MappingR2dbcConverter.java:294) ~[spring-data-r2dbc-1.2.5.jar:1.2.5]
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readFrom(MappingR2dbcConverter.java:166) ~[spring-data-r2dbc-1.2.5.jar:1.2.5]
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readEntityFrom(MappingR2dbcConverter.java:294) ~[spring-data-r2dbc-1.2.5.jar:1.2.5]
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readFrom(MappingR2dbcConverter.java:166) ~[spring-data-r2dbc-1.2.5.jar:1.2.5]
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readEntityFrom(MappingR2dbcConverter.java:294) ~[spring-data-r2dbc-1.2.5.jar:1.2.5]
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readFrom(MappingR2dbcConverter.java:166) ~[spring-data-r2dbc-1.2.5.jar:1.2.5]
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readEntityFrom(MappingR2dbcConverter.java:294) ~[spring-data-r2dbc-1.2.5.jar:1.2.5]
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readFrom(MappingR2dbcConverter.java:166) ~[spring-data-r2dbc-1.2.5.jar:1.2.5]

person Community    schedule 20.03.2021    source источник


Ответы (2)


R2DBC не поддерживает отношения, поэтому аннотация JoinColumn не будет работать. Вместо этого вы можете создать DueRepository и получить этот объект вручную.

person sawim    schedule 20.03.2021
comment
Пожалуйста, поделитесь небольшим кодом - person ; 20.03.2021
comment
Тогда не будет блокировки? - person ; 20.03.2021
comment
Поэтому мне приходится использовать сопоставление, когда блок кода слишком велик. - person ; 20.03.2021
comment
Это будет неблокирующим, если вы напишете его правильно;) вы можете создать класс TaskDto, который содержит все поля, которые вы хотите отправить в ответ, изменить поле Due due в классе Task на Integer dueId, а затем в TaskManager выбрать и сопоставить все необходимые данные: tasksRepository.findAll().flatMap(task -> dueRepository.findById(task.getDueId()).map(due -> new TaskDto(...))) - person sawim; 20.03.2021
comment
В качестве альтернативы рассмотрите возможность объединения Task с таблицей Due, поскольку ее отношение один к одному - person sawim; 20.03.2021
comment
окей я понял спасибо - person ; 20.03.2021

Хорошо, приятель, во-первых, почему именно эта сущность Due должна быть отдельной сущностью? Я имею в виду, что у задачи может быть крайний срок, и она может повторяться. Будь проще.

Что касается кода, независимо от аспектов моделирования предметной области:

Используйте Long или UUID в качестве типов полей ID. Лично я никогда не видел int в производстве.

Создайте CrudRepo для этих сущностей Due, чтобы проверить, можете ли вы запрашивать их самостоятельно. Напишите тест, чтобы убедиться в этом.

Я предполагаю, что аннотация JoinTable каким-то образом избыточна и/или неправильно настроена. Попробуйте Due.ID вместо Due_ID, чтобы указать, какое поле объекта Due он должен принимать.

person ubt3    schedule 20.03.2021
comment
Мне нужно реактивное программирование, поэтому я должен писать с помощью reactivecrudrepository. - person ; 20.03.2021
comment
В приведенном мне примере это дано с должным отношением один к одному, так и должно быть. - person ; 20.03.2021
comment
Я думаю проблема в них, но спасибо за помощь - person ; 20.03.2021