Reputation: 166
Repository repo
Repository otherRepo
foreach entity : repo.FindAll() {
entityFind = otherRepo.FindById(entity.Prop)
if (entityFind != null) {
return entityFind
}
}
How could I do this using the spring reactive?
I could use blockFirst() to search in otherRepo but it would break the reaction chain
I also have tried use a handle() to control the flow but I don't get to break the flow when I find an item
Any idea? Thanks
Upvotes: 1
Views: 788
Reputation: 28301
The answer from vins
is assuming non-reactive repository, so here it is in a fully reactive style:
return repo.findAll() //assuming reactive repository, which returns Flux<Entity>
.flatMap(entity -> otherRepo.findById(entity.property)) //findById returns an empty Mono if id not found, which basically gets ignored by flatMap
.next(); //first record is turned into a Mono, and the Flux is cancelled
Note that as you've stated, this can lead to unnecessary requests being made to Cassandra (and then cancelled by the next()
). This is due to flatMap
allowing several concurrent requests (256 by default). You can either reduce the parallelism
of flatMap
(by providing a second parameter, an int
) or use concatMap
to perform findById
queries serially.
Upvotes: 1
Reputation: 15370
If you have repos like this, for each record of repo1, if you need to find a record from repo2, you could probably join the tables using spring data JPQL & use your custom method instead as your current approach could have performance impact.
As you seem to be interested only in the first record, Just to give you an idea, We can achieve something like this.
return Flux.fromIterable(repo.findAll()) //assuming it returns a list
.map(entity -> otherRepo.findById(entity.property)) // for each entity we query the other repo
.filter(Objects::nonNull) // replace it with Optional::isPresent if it is optional
.next(); //converts the flux to mono with the first record
Upvotes: 1