【问题标题】:Java DataLoader: Graphql query mismatches resultsJava DataLoader:Graphql 查询结果不匹配
【发布时间】:2022-02-07 21:40:10
【问题描述】:

我在我的项目中使用 boot-graphql-kick-start。当我使用 Dataloader 时,结果不匹配。我哪里错了?你能帮帮我吗?

查询:

query USE_ROLES_BY_PROJECT_ID($projectId: Int) {  # parameter value  =3 
  userRolesByProjectId(projectId:$projectId) {
    id
    roleId
    projectId
    role {
      id
      name
      shortCode
    }
  }

结果:

{
  "data": {
    "userRolesByProjectId": [
      {
        "id": 2,
        "projectId": 3,
        "roleId": 5,
        "role": {
          "id": 8,
          "name": "TESTER",
          "shortCode": "TESTER"
        }
      },
      {
        "id": 81,
        "projectId": 3,
        "roleId": 8,
        "role": {
          "id": 5,
          "name": "PROJECTADMIN",
          "shortCode": "PROJECTADMIN"
        }
      }
    ]
  }
}

ResultForDetail

实体:我与我的 RoleEntity 有多对一关系

@Entity
public class UserRole extends BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_cfcs_user_role")
    @Column(name = "id")
    private Long id;

    @Column(name = "role_id")
    private Long roleId;

    @Column(name = "project_id")
    private Long projectId;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "role_id", referencedColumnName = "id", insertable = false, updatable = false)
    private Role role;
}

查询解析器:

@Component
public class UserRolesQueryResolver implements GraphQLQueryResolver {
    private final UserRoleService userRolesService;
    
    public List<UserRole> userRolesByProjectId(Long projectId){
        return userRolesService.getUserRole(projectId);
    }
}

@Component
public class UserRoleResolver 
implements GraphQLResolver<UserRole> {
    private final IRoleService roleService;
 
    public CompletableFuture<Role> role(UserRole userRole, DataFetchingEnvironment dfe) {
        final DataLoader<Long, Role> dataloader = dfe.getDataLoaderRegistry()
                .getDataLoader("userRoleRoleDataLoader");
        return dataloader.load(userRole.getRoleId());
    }
}

DataLoader 方法:我将 BatchLoader 用于 n+1。

 private void role(DataFetchingEnvironment dfe) {
        BatchLoader<Long, Role> userRoleRoleDataLoader =
                roles -> CompletableFuture.supplyAsync(() -> {
                    return roleService.findByIdIn(roles);
                });
        dfe.getDataLoaderRegistry().register("userRoleRoleDataLoader",
                DataLoader.newDataLoader(userRoleRoleDataLoader));
    }

休眠查询:在 dataLoader 中,我正在查看结果。似乎是正确的

select role0_.id         as id1_18_,
       role0_.name       as name9_18_,
       role0_.short_code as short_c10_18_
from app_role role0_
where (role0_.is_actv = 1)
  and (role0_.id in (?, ?))

【问题讨论】:

    标签: java spring-boot graphql dataloader


    【解决方案1】:

    我遇到了同样的问题,解决方案是根据输入对数据加载器的输出进行排序。输出的顺序必须与输入的顺序相匹配。 对你来说,这可能意味着这样的事情:

    private void role(DataFetchingEnvironment dfe) {
            BatchLoader<Long, Role> userRoleRoleDataLoader =
                    roleIds -> CompletableFuture.supplyAsync(() -> {
                        List<Role> roles = roleService.findByIdIn(roleIds);
                        roles.sort(Comparator.comparing(n -> roleIds.indexOf(n.getId())));
                        return roles;
                    });
            dfe.getDataLoaderRegistry().register("userRoleRoleDataLoader",
                    DataLoader.newDataLoader(userRoleRoleDataLoader));
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多