简体   繁体   中英

How to do a join for every object in a Flux with a database call returning a Mono

I have two database calls one returning a Flux and another returning a Mono

The LegacyPerson class contains an legacyPersonId and a name. The PersonKey class contains and legacyPersonId and a PersonID

I want to get as result an Mono<List> where the Person class contains an legacyPersonId and an PersonId. So i have to determine the id for every legacyPerson in the flux without blocking.

        class LegacyPerson {
            Integer legacyId;
            String name;
        }

        @Builder
        class Person {
            UUID id;
            Integer legacyId;
            String name;
        }

        class PersonKey {
            UUID id;
            Integer legacyId;
        } 

two repositories:

        @Repository
        public interface RepositoryKey extends ReactiveCrudRepository<PersonKey, UUID> {
            Mono<PersonKey> findByPensioennummer(Integer pensioennummer);
        }
        @Repository
        public interface RepositoryPerson extends ReactiveCrudRepository<LegacyPerson, UUID> {
            Flux<LegacyPerson> findByName(String name);
        }

This is what i have tried

       class Service {
            RepositoryKey repKey;
            RepositoryPerson repPerson;
            public Mono<List<Person>> getPersons(String name) {
                Flux<LegacyPerson> legacyPersonFlux = repPerson.findByName(name);

                legacyPersonFlux.map(person -> map(repKey.findByPensioennummer(person.legacyId), person));
            }

            private Person map(UUID id, LegacyPerson legacyPerson) {
                return Person.builder().id(id).name(legacyPerson.name).legacyId(legacyPerson.legacyId).build();
            }
        }

I get an error that the map method expects an UUID an not an Mono. I can change it to Mono but I don't want to change the Id in my domain object Person.

Any help would be greatly appreciated!

That doesn't make sense. public Person getPerson(String name) is not reactive. You need, at least, public Mono<Person> getPerson(String name) . Further, what do you plan to do if the Flux<LegacyPerson> findByName(String name) returns more than one result? At first consider changing it to Mono<LegacyPerson> findByName(String name) .

RepositoryKey repKey = new RepositoryKey();;
RepositoryPerson repPerson = new RepositoryPerson();

public Mono<Person> getPerson(String name) {
    Flux<LegacyPerson> legacyPersonFlux = repPerson.findByName(name);
    
    return  legacyPersonFlux.next()
            .flatMap(legacyPerson -> repKey.findByPensioennummer(legacyPerson.legacyId).map(pk->map(pk.id, legacyPerson)));
}

private Person map(UUID id, LegacyPerson legacyPerson) {
    return Person.builder().id(id).name(legacyPerson.name).legacyId(legacyPerson.legacyId).build();
}   
private void run() {
    getPerson("me").subscribe(System.out::println);
}



static class LegacyPerson {
    Integer legacyId;
    String name;
}

@Builder
@Data
static class Person {
    UUID id;
    Integer legacyId;
    String name;
}

static class PersonKey {
    UUID id;
    Integer legacyId;
}
public class RepositoryKey {
    Mono<PersonKey> findByPensioennummer(Integer pensioennummer) {
        PersonKey pk = new PersonKey();
        pk.legacyId = pensioennummer;
        pk.id = UUID.randomUUID();
        return Mono.just(pk);
    }
}
public class RepositoryPerson {
    Flux<LegacyPerson> findByName(String name) {
        LegacyPerson lp = new LegacyPerson();
        lp.legacyId = 1;
        lp.name = name;
        return Flux.just(lp); 
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM