Spring-data-aerospike `findAll (ids)` возвращает NULL в результате - PullRequest
0 голосов
/ 08 октября 2018

Spring-data-aerospike метод findAll(Iterable<ID> ids) возвращает список с NULL s для несуществующих объектов.

В случае, если некоторые из сущностей do существуют, а некоторые из них не существуют - результатом будет Iterable как с NULL s, так и с существующими сущностямикомбинированный: [entity1, null, entity2, null] .

Это бесполезно при обработке результатов findAll(Iterable<ID> ids) из-за NPE s.

Просмотрев исходный код, я нашел следующий метод в классе 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); вместо?

Upd.

Чтобы убедиться, что ожидаемое поведение НЕ возвращает NULL s Я изучил реализацию 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();
}

Ответы [ 2 ]

0 голосов
/ 02 ноября 2018

Проблема была исправлена ​​ в последнем снимке.

Как только smbdy из команды Aerospike выпустит новую версию - вы можете использовать ее.До сих пор вы должны фильтровать нули.Это расстраивает, я согласен:)

0 голосов
/ 09 октября 2018

Это нормальное поведение в соответствии с дизайном?Отличный вопрос и ответ зависит от того, что вы считаете нормальным.

Метод findByIDs (...) в конечном итоге реализован Aerospike "get (BatchPolicy policy, Key [] keys)".Метод вернет массив записей, упорядоченных в соответствии с порядком ключей.Если запись не существует, возвращается ноль.

С точки зрения Aerospike, результаты верны.Но действительно ли это с точки зрения Spring Data?Как Spring показывает, что некоторые записи недоступны для набора запрошенных идентификаторов?

...