Spring-data-aerospike
方法findAll(Iterable<ID> ids)
返回带有NULL
的不存在实体的列表。
如果某些实体存在存在而某些实体不存在-结果将是Iterable
,同时有两个NULL
和现有实体的组合: [entity1,null,entity2,null] 。
由于findAll(Iterable<ID> ids)
的原因,在处理NPE
的结果期间没有用。
查看源代码后,我在类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;
}
因此,问题是:
if(entity != null) tList.add(entity);
?更新。
为确保预期的行为是 NOT 返回NULL
,我研究了org.springframework.data.jpa.repository.JpaRepository
(特别是类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();
}
答案 0 :(得分:3)
问题是最新快照中的fixed。
Aerospike团队的smbdy提供新版本后,您就可以使用它。 到目前为止,您应该过滤null。我同意,这真令人沮丧:)
答案 1 :(得分:2)
这是正常现象吗?一个很好的问题和答案取决于您认为正常的情况。
findByIDs(...)方法最终由Aerospike“ get(BatchPolicy policy,Key [] keys)”实现。该方法将返回一个Records数组,该数组的顺序与键的顺序匹配。如果记录不存在,将返回null。
从Aerospike的角度来看,结果是正确的。但是从Spring Data的角度来看是否有效? Spring如何表明某些记录不适用于该组请求的ID?