如何将对象保存到通量内的反应式存储库

And*_*kiy 2 java-8 project-reactor spring-webflux

我有问题的答案清单。我想保存这些答案,然后(在 mongo 给他们一个 id 之后)将它们添加到他们的问题中。

现在我这样做:

public Flux<Answer> createAnswers(List<Answer> answers) {
    return answerRepository.saveAll(answers)
            .map(answer -> {
                questionRepository.findById(answer.getQuestionId())
                        .subscribe(question -> {
                            question.getAnswers().removeIf(ans -> Objects.equals(ans.getId(), answer.getId()));
                            question.getAnswers().add(answer);
                            questionRepository.save(question).block();
                        });
                return answer;
            });
}
Run Code Online (Sandbox Code Playgroud)

我也尝试过..saveAll(answers).doOnNext()doOnEach()但是这样问题不会被保存。

似乎 map 用于转换数据而不是用于对每个元素进行操作。此外,我对调用block().

有没有更好的方法来实现我的目标?

Bri*_*zel 6

您永远不应该在返回响应式类型本身的方法中对 a或 a调用subscribe/ 。blockFluxMono

这样做将使当前管道与您要实现的目标分离。最好的情况是,这将破坏背压支持。在许多情况下,这也可能会以令人惊讶的方式中断。例如,如果您的方法正在处理 HTTP 请求/响应或某种类型的会话,则响应/会话可能会关闭,而您的其他订阅者仍在尝试对其执行某些操作。

我相信这样的事情更一致(尽管我在这里遗漏了很多上下文,所以它可能不是实现这一目标的最佳方式):

public Flux<Answer> createAnswers(List<Answer> answers) {
        return answerRepository.saveAll(answers)
                .flatMap(answer -> {
                    return questionRepository
                            .findById(answer.getQuestionId())
                            .flatMap(question -> {
                                question.getAnswers().removeIf(ans -> Objects.equals(ans.getId(), answer.getId()));
                                question.getAnswers().add(answer);
                                return questionRepository.save(question);
                            })
                            .thenReturn(answer);
                });
    }
Run Code Online (Sandbox Code Playgroud)