Java 在同一块中使用Flux和Mono时获得堆栈溢出错误

Java 在同一块中使用Flux和Mono时获得堆栈溢出错误,java,reactive-programming,spring-webflux,Java,Reactive Programming,Spring Webflux,我正在spring boot项目中使用WebFlux。我有一段注册用户的代码,它首先检查提交的电子邮件是否存在于这样的数据库中 userRepository.findByEmail(userDto.getEmail()) .flatMap(t -> { UserAlreadyExistException userAlreadyExistException = new UserAlreadyExistException("Th

我正在spring boot项目中使用
WebFlux
。我有一段注册用户的代码,它首先检查提交的电子邮件是否存在于这样的数据库中

userRepository.findByEmail(userDto.getEmail())
            .flatMap(t -> {
                UserAlreadyExistException userAlreadyExistException = new UserAlreadyExistException("There is an account with this email address: " + userDto.getEmail());
                Response<?> response = Response.duplicateEntity();
                response.addErrorMsgToResponse(userAlreadyExistException.getMessage(), userAlreadyExistException);
                return Mono.<ResponseEntity<?>>just(ResponseEntity.status(HttpStatus.NOT_ACCEPTABLE)
                        .body(response));
            })
 .switchIfEmpty(Mono.defer(() -> Mono.zip(companyRepository.findById(userDto.getCompanyUuid()), 
                    roleRepository.findAllById(userDto.getRolesUuids()).collectList()))
                    .flatMap(t -> userRepository.save(User.builder()
                            .firstName(userDto.getFirstName())
                            .lastName(userDto.getLastName())
                            .company(t.getT1())
                            .status(userDto.isEnabled() ? BaseModel.Status.ENABLED : BaseModel.Status.DISABLED)
                            .accountStatus(User.AccountStatus.ACCOUNT_ACTIVATED)
                            .email(userDto.getEmail())
                            .profilePhoto(userDto.getProfilePhoto())
                            .roles(t.getT2()).phone(userDto.getPhone())
                            .build()))
                    .flatMap(__ -> Mono.<ResponseEntity<?>>just(ResponseEntity.status(HttpStatus.OK).body(Response.ok())))
                    .switchIfEmpty(Mono.defer(() -> Mono.just(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                            .body(Response.badRequest())))))
当我运行这段代码时,它会运行到
zip
Mono.zip(companyRepository.findById(userDto.getcompanyuid()),roleRepository.findAllById(userDto.getRolesUuids()).collectList()),在那里它进入一个无限循环;在角色之间循环,直到我得到一个stackoverflow,我真的不理解这种行为,我试着将其更改为

 .switchIfEmpty(Mono.defer(() -> companyRepository.findById(userDto.getCompanyUuid())
                    .flatMap(company -> roleRepository.findAllById(userDto.getRolesUuids())
                            .collectList()
                            .flatMap(roles -> userRepository.save(User.builder()
                                    .firstName(userDto.getFirstName())
                                    .lastName(userDto.getLastName())
                                    .company(company)
                                    .status(userDto.isEnabled() ? BaseModel.Status.ENABLED : BaseModel.Status.DISABLED)
                                    .accountStatus(User.AccountStatus.ACCOUNT_ACTIVATED)
                                    .email(userDto.getEmail())
                                    .profilePhoto(userDto.getProfilePhoto())
                                    .roles(roles)
                                    .phone(userDto.getPhone())
                                    .build()))

                    )
                    .flatMap(__ -> Mono.<ResponseEntity<?>>just(ResponseEntity.status(HttpStatus.OK).body(Response.ok())))
                    .switchIfEmpty(Mono.defer(() -> Mono.just(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                            .body(Response.badRequest()))))))
.switchIfEmpty(Mono.defer(()->companyRepository.findById(userDto.getcompanyuid())
.flatMap(公司->角色定位.findAllById(userDto.getRolesUuids())
.LIST()
.flatMap(角色->用户存储库.save(User.builder())
.firstName(userDto.getFirstName())
.lastName(userDto.getLastName())
.公司(公司)
.status(userDto.isEnabled()?BaseModel.status.ENABLED:BaseModel.status.DISABLED)
.accountStatus(用户.accountStatus.ACCOUNT\u已激活)
.email(userDto.getEmail())
.profilePhoto(userDto.getProfilePhoto())
.角色(角色)
.phone(userDto.getPhone())
.build())
)

.flatMap(_->Mono.首先,请尝试避免嵌套平面图。这被认为是一种不好的做法

其次,您使用的是zip,因此,如果提供的公司或角色不存在,则应用程序会给出一个错误

您只需通过以下方式即可实现:

companyRepository.findById(userDto.getCompanyUuid()
   .switchIfEmpty(Mono.deferWithContext(context -> {
          //do some logging or something with context
          return Mono.error(new SomeException());
        }))
   .zipWith(...)
   ...

首先,请尽量避免嵌套平面图。这被认为是一种不好的做法

其次,您使用的是zip,因此,如果提供的公司或角色不存在,则应用程序会给出一个错误

您只需通过以下方式即可实现:

companyRepository.findById(userDto.getCompanyUuid()
   .switchIfEmpty(Mono.deferWithContext(context -> {
          //do some logging or something with context
          return Mono.error(new SomeException());
        }))
   .zipWith(...)
   ...

你能提供一个容易克隆的gist或github项目的链接吗?这将帮助我更快地解决问题。你的第一步应该是清理你的代码。它太密集和复杂了。没有人能阅读。其次,你应该发布你看到的实际错误。你能提供一个可以克隆的gist或github项目的链接吗很容易克隆。这将帮助我更快地解决问题。你的第一步应该是清理你的代码。它太密集和复杂了。没有人能阅读。其次,你应该发布你看到的实际错误。它很有效!感谢对嵌套平面图的提醒!感谢对嵌套平面图的提醒