Reputation: 178
I have list of answers on questions. I want to save those answers and then (after mongo gives them an id) add them to their questions.
Now I'm doing it this way:
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;
});
}
I also tried with ..saveAll(answers).doOnNext()
and doOnEach()
but this way questions are not saved.
It seems that map is used to transform data but not for doing operations on each element. Also I'm a bit confused with call to block()
.
Is there a better way to achieve my aim?
Upvotes: 3
Views: 5223
Reputation: 59086
You should never call subscribe
/block
on a Flux
or a Mono
within a method that returns a reactive type itself.
Doing so will decouple the current pipeline with what you're trying to achieve. Best case scenario, this will break backpressure support. In many cases, this might also break in surprising ways; for example, if your method is dealing with HTTP request/response or a session of some sort, the response/session might get closed with your other subscriber is trying to do something on it still.
I believe something like this is more consistent (although I'm missing a lot of context here, so it might not be the best way to achieve this):
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);
});
}
Upvotes: 7