David Suárez
David Suárez

Reputation: 166

Spring reactive: Chaining repository results

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

Answers (2)

Simon Baslé
Simon Baslé

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

vins
vins

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

Related Questions