Spring-data-aerospike `findAll(ids)` returns 结果为 NULL

Spring-data-aerospike `findAll(ids)` returns NULLs in result

Spring-data-aerospike 方法 findAll(Iterable<ID> ids) returns 列出 NULL 不存在的实体。

如果某些实体 存在而其中一些 存在 - 结果将是 Iterable结合 NULL 和现有实体:[entity1, null, entity2, null].

在处理 findAll(Iterable<ID> ids) 的结果期间没有用,因为 NPEs。

在查看源代码后,我在 class org.springframework.data.aerospike.core.AerospikeTemplate 中找到了以下方法:

@Override
public  <T> List<T> findByIDs(Iterable<Serializable> IDs, Class<T> type){
    AerospikePersistentEntity<?> entity = mappingContext.getPersistentEntity(type);
    List<Key> kList = new ArrayList<Key>();
    IDs.forEach(id -> kList.add(new Key(this.namespace, entity.getSetName(), id.toString())));
    Record[] rs = this.client.get(null, kList.toArray(new Key[kList.size()]));
    final List<T> tList = new ArrayList<T>();
    for(int i=0; i < rs.length; i++)
        tList.add(mapToEntity(kList.get(i), type, rs[i])); // <--- mapToEntity here may return NULL (is it a bug or by design?)
    return tList;
}

因此,问题是:

  1. 这是设计的正常行为吗?
  2. 不应该是:if(entity != null) tList.add(entity); 吗?

更新

为了确保预期的行为是 NOT 返回 NULLs 我研究了 org.springframework.data.jpa.repository.JpaRepository 的实现(特别是 class org.springframework.data.jpa.repository.support.SimpleJpaRepository) 并找到了关于我的案例的以下代码:

public List<T> findAllById(Iterable<ID> ids) {

    Assert.notNull(ids, "The given Iterable of Id's must not be null!");

    if (!ids.iterator().hasNext()) {
        return Collections.emptyList();
    }

    if (entityInformation.hasCompositeId()) {

        List<T> results = new ArrayList<T>();

        for (ID id : ids) {
            findById(id).ifPresent(results::add); // <--- here is what I meant above - we add only existing entities
        }

        return results;
    }

    ByIdsSpecification<T> specification = new ByIdsSpecification<T>(entityInformation);
    TypedQuery<T> query = getQuery(specification, Sort.unsorted());

    return query.setParameter(specification.parameter, ids).getResultList();
}

这是设计的正常行为吗?一个很好的问题和答案取决于你认为正常的。

findByIDs(...) 方法最终由 Aerospike "get(BatchPolicy policy, Key[] keys)" 实现。该方法将 return 排列的记录数组与键的顺序相匹配。如果记录不存在,将 returned 为 null。

从 Aerospike 的角度来看,结果是正确的。但从 Spring 数据的角度来看它是否有效? Spring 如何表示某些记录对于请求的 ID 集不可用?

最新快照中的问题 fixed

只要 Aerospike 团队的 smbdy 提供了新版本,您就可以使用它。 到目前为止,您应该过滤空值。这令人沮丧,我同意 :)