不存在类型变量U的实例,因此Foo符合CompletionStage <u>

时间:2018-08-17 06:57:51

标签: java lambda java-8 completable-future

我已经在这里待了几个小时,但似乎无法解开它。错误与这段代码有关:

enter image description here

(此问题底部的完整代码。我正在使用屏幕截图直观地显示问题。)

错误本身是:

  

不存在类型变量U的实例,因此GetUsersForAdAccountResponse符合CompletionStage

thenCompose链的最开始,我擦除了return,并使用IntelliJ的“引入局部变量...” 功能来查看整个链(直到第1118行,包括第1118行)正在返回:

enter image description here

结果是

final CompletionStage<U> uCompletionStage = ...

但是您可以看到包围方法的返回类型为

public CompletionStage<GetUsersForAdAccountResponse> ...

是什么导致编译器无法推断GetUsersForAdAccountResponse? (再次,通常这里是return。)

在此过程中,我还尝试在每个thenCompose处引入局部变量,它们似乎都是正确的。每个产生一个CompletionStage<Foo>,下一个thenCompose提供一个期望Foo的lambda并产生CompletionStage<Bar>,依此类推。 (在一次代码重组中,我确实看到了一个嵌套的CompletionStage<CompletionStage<Foo>>,但我认为那是我自己重写的产物。)


我不知道是否有帮助,但这是整个方法:

  @Override
  public CompletionStage<GetUsersForAdAccountResponse> getUsersForAdAccount(
      RequestContext context, GetUsersForAdAccountRequest request) {

    Uuid adAccountId = request.getAdAccountId();

    return verifyAuthorization(context,
        PortcullisTemplates.Action.GET_USERS_FOR_AD_ACCOUNT.getName(),
        portcullisTemplates.topOrganizationResource())
        .thenCompose(auditLogPrincipal -> jdbiExecutor.executeInTransaction(handler -> {

              // We purposely safeguard the account lookup as well behind Portcullis.
              AdAccountDao adAccountDao = handler.attach(AdAccountDao.class);
              if (adAccountDao.getAdAccountById(adAccountId) == null) {
                throw new ValidationException(SERVICE_NAME,
                    "Ad account not found: " + UuidUtils.toString(adAccountId));
              }

              AdAccountRoleUserMappingDao roleDao = handler.attach(AdAccountRoleUserMappingDao.class);

              List<String> roleNames = request.getRoleNamesList();
              return roleNames.isEmpty() ?
                     roleDao.getAdAccountRoleUserMappingsByAdAccount(adAccountId) :
                     roleDao.getAdAccountRoleUserMappingsByAdAccountAndRoles(adAccountId, roleNames);

        })).thenCompose(adAccountRoleUserMappings -> jdbiExecutor.execute(UserDao.class, userDao -> {
          return userDao
              .getUsersBy]UserIds(
                  adAccountRoleUserMappings.stream()
                      .map(AdAccountRoleUserMapping::userId)
                      .collect(Collectors.toList())
              ).stream()
                  .collect(Collectors.toMap(
                      User::userId,
                      user -> new EncryptedFieldsBuilder()
                          .firstName(user.encryptedFirstName())
                          .lastName(user.encryptedLastName())
                          .email(user.encryptedEmail())
                          .build()
              ));
        }).thenCompose(
            userEncryptedFields -> padlockService.decryptUserAccounts(userEncryptedFields)
        ).thenCompose(decryptedUsers -> GetUsersForAdAccountResponse.newBuilder()
            .addAllUserWithRole(
                adAccountRoleUserMappings.stream()
                    .filter(mapping -> decryptedUsers.containsKey(mapping.userId()))
                    .map(mapping -> UserWithRole.newBuilder()
                        .setAccount(decryptedUsers.get(mapping.userId()))
                        .setRoleName(mapping.roleName())
                        .build())
                    .collect(Collectors.toSet())
            ).build()
        ));
  }

1 个答案:

答案 0 :(得分:4)

链中的最后一个thenCompose应该是thenApply。传递给它的函数返回一个GetUsersForAdAccountResponse而不是CompletionStage

thenComposeflatMap中的CompletableFuture。它需要一个返回CompletionStage并展平结果的函数。