如何用reactor保存嵌套实体?

kxe2p93d  于 2021-07-13  发布在  Java
关注(0)|答案(0)|浏览(314)

我将spring与r2dbc一起使用,需要执行以下操作:

  1. for (var q: quiz.quizzes()) {
  2. Set<UUID> qsIds = new LinkedHashSet<>();
  3. for (var qs: q.questions()) {
  4. var ansids = answerRepository
  5. .saveAll(mapToAnswerEntity(qs.getAnswers()))
  6. .collectList().toFuture()
  7. .get()
  8. .stream()
  9. .map(AnswerEntity::id)
  10. .collect(Collectors.toSet());
  11. var qe = QuestionEntity.builder().id(qs.getId()).answerIds(ansids).title(qs.getTitle()).build();
  12. var id = questionRepository.save(qe).toFuture().get().id();
  13. qsIds.add(id);
  14. }
  15. var newQ = quizRepository
  16. .save(
  17. toQuizEntity(q, qsIds)).toFuture().get();
  18. var updatedCourse = courseRepository.findById(courseId).toFuture().get().addQuizToCourse(newQ.id());
  19. courseRepository.save(updatedCourse);
  20. }
  21. return Mono.empty();

问题是我不能使用.get(),因为需要reactor(我使用的是webflux)。
我尝试了以下方法:

  1. return Flux.fromIterable(quiz.quizzes())
  2. .flatMap(q-> Flux.zip(Flux.just(q), Flux.fromIterable(q.questions())))
  3. .flatMap(t->
  4. Flux.zip(Flux.just(t.getT1()),
  5. Flux.defer(()->Flux.just(t.getT2())),
  6. Mono.from(answerRepository.saveAll(mapToAnswerEntity(t.getT2().getAnswers())).collectList())))
  7. .flatMap(t->
  8. Flux.zip(
  9. Flux.just(t.getT1()),
  10. Flux.just(toQuestionEntity(t)).collect(Collectors.toSet())))
  11. .flatMap(t-> Flux.zip(Flux.just(t.getT1()), questionRepository.saveAll(t.getT2()).collectList()))
  12. .map(t-> toQuizEntity(t.getT1(), t.getT2().stream().map(QuestionEntity::id).collect(Collectors.toSet())))
  13. .flatMap(t-> quizRepository.save(t))
  14. .flatMap(q-> courseRepository.findById(courseId).map(x->x.addQuizToCourse(q.id())))
  15. .flatMap(c-> courseRepository.save(c))
  16. .then(Mono.empty());

然而,这并没有返回我所期望的所有结果。基本上只保存相对于第一个测验的第一个或最后一个结果(问题和答案)。这两个测验(我用于测试目的)保存在数据库中,只是它们的“依赖项”受到影响。2个问题(每个测验1个)已保存,其他问题未保存。答案也差不多。
编辑
我试过这种方法,它解决了以前的问题,但现在只有一门课程被添加到quicky\u id列。

  1. return Flux.fromIterable(quiz.quizzes())
  2. .flatMap(q-> Flux.fromIterable(q.questions())
  3. .flatMap(qs-> answerRepository
  4. .saveAll(mapToAnswerEntity(qs.getAnswers()))
  5. .collect(Collectors.toSet())
  6. .flatMap(l-> Mono.just(l.stream().map(AnswerEntity::id).collect(Collectors.toSet())))
  7. .flatMap(l -> Mono.defer(()-> Mono.just(toQuestionEntity(qs,l)))))
  8. .collect(Collectors.toSet())
  9. .flatMap(l-> questionRepository.saveAll(l).collect(Collectors.toSet()))
  10. .map(l->l.stream().map(QuestionEntity::id).collect(Collectors.toSet()))
  11. .flatMapMany(qsl-> quizRepository.save(toQuizEntity(q, qsl)))
  12. .doOnNext(System.out::println))
  13. .flatMap(qe->Flux.defer(()->courseRepository.findById(courseId).map(x->x.addQuizToCourse(qe.id())).flatMap(c->courseRepository.save(c))))
  14. .doOnNext(System.out::println)
  15. .then(Mono.empty());

这就是为课程添加测验的原因:x.addquiztocourse(qe.id())
这是日志记录的结果:

  1. QuizEntity(id=e9e13855-2c42-456e-9fab-a0865ad96a3f, quizName=1111, quizContent=julia2020 2 test quiz content, questionIds=[a5d576f0-afc9-4312-9f29-cdc018eb635a, cc7282c5-ffd0-4750-9180-ca5e50d4f515])
  2. QuizEntity(id=73315bac-dce0-4595-91c2-85fe2a2e4765, quizName=2222, quizContent=julia2020 test quiz content, questionIds=[b4b1765e-e41a-427b-9073-ad2b16dabe3a, 0e9ad984-b63a-4ca4-aa12-efa1a3e7ae6a])
  3. CourseAggregate(id=776fff36-34d9-4b53-8395-c72ee4816f3f, courseName=Mammia course, description=<p>Test Courseasdsadsadsasadasdsa</p>, status=DRAFT, teacherId=79ab22d9-af94-49f1-a25e-c74bada7ce6f, studentIds=[], lessonIds=[4f364a50-bc28-4d75-9f76-71ff43d30ebf, eaaab4ae-6ab4-4a14-a906-259293780e17, 28db0295-82ab-4074-aff7-5e10374191b5], quizIds=[e9e13855-2c42-456e-9fab-a0865ad96a3f])
  4. CourseAggregate(id=776fff36-34d9-4b53-8395-c72ee4816f3f, courseName=Mammia course, description=<p>Test Courseasdsadsadsasadasdsa</p>, status=DRAFT, teacherId=79ab22d9-af94-49f1-a25e-c74bada7ce6f, studentIds=[], lessonIds=[4f364a50-bc28-4d75-9f76-71ff43d30ebf, eaaab4ae-6ab4-4a14-a906-259293780e17, 28db0295-82ab-4074-aff7-5e10374191b5], quizIds=[73315bac-dce0-4595-91c2-85fe2a2e4765])

如您所见,最后一个课程聚合不包含上一个,而只包含当前测验id。
编辑2:我用delayuntil解决了这个问题:

  1. return Flux.fromIterable(quiz.quizzes())
  2. .flatMap(q-> Flux.fromIterable(q.questions())
  3. .flatMap(qs-> answerRepository
  4. .saveAll(mapToAnswerEntity(qs.getAnswers()))
  5. .collect(Collectors.toSet())
  6. .flatMap(l-> Mono.just(l.stream().map(AnswerEntity::id).collect(Collectors.toSet())))
  7. .flatMap(l -> Mono.defer(()-> Mono.just(toQuestionEntity(qs,l)))))
  8. .collect(Collectors.toSet())
  9. .flatMap(l-> questionRepository.saveAll(l).collect(Collectors.toSet()))
  10. .map(l->l.stream().map(QuestionEntity::id).collect(Collectors.toSet()))
  11. .flatMapMany(qsl-> quizRepository.save(toQuizEntity(q, qsl)))
  12. .doOnNext(System.out::println))
  13. .delayUntil(qe-> courseRepository.findById(courseId).map(x->x.addQuizToCourse(qe.id())).flatMap(c->courseRepository.save(c)))
  14. .doOnNext(System.out::println)
  15. .then(Mono.empty());

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题