首页 > 解决方案 > 带有可迭代的Spring数据findAllBy返回空数组

问题描述

使用 a和自定义方法返回具有匹配属性的所有对象是在调用ReactiveMongoRepository以外的任何对象上返回一个空集合。findAllById

我想知道我是否在这里误解了某些东西,而这只适用于 ID 字段或其他东西?

我正在使用的界面:

@Repository
public interface VideoRepository extends ReactiveMongoRepository<Video, String> {
    Flux<Video> findAllByHash(Iterable<Long> hash);
}

我只是通过以下方式调用它:

@GetMapping("duplicates")
public Flux<Video> duplicates() {
    // {...}

    List<Long> hashList = duplicateDTOs
            .stream()
            .map(duplicateDTO -> Long.valueOf(duplicateDTO.getHash()))
            .collect(Collectors.toList());

    return videoRepository.findAllByHash(hashList);
}

作为参考,有问题的 POJO:

@Data
@Builder
@Document
@AllArgsConstructor
@NoArgsConstructor
public class Video {

    @Id
    String id;

    long hash;

    //{...}
}

我已经确认我正在传递三个值,它们与POJO上设置hashList的自定义hash属性相匹配。Video

这是否不应该返回所有Video具有匹配自定义hash属性的对象,就像我对属性做同样的事情时所做的那样id

标签: javaspringspring-bootspring-dataspring-mongo

解决方案


findAllByHashIn(Collection<Long> hashes);

我以前从未使用过Iterable作为自定义 JPA 存储库方法的参数,但我会将名称翻译findAllByHash为“获取单个哈希值并查找拥有该值的所有条目”,并且签名将是findAllByHash(Long hash).

您的动机有点不同:您希望在搜索过程中使用所有哈希值。根据这张表

Keyword | Sample                             | JPQL snippet

In      | findByAgeIn(Collection<Age> ages)  | … where x.age in ?1

Spring JPA 支持逻辑IN并接受 的子类Collection,因此它可以是

findAllByHashIn(Collection<Long> hashes);
findAllByHashIn(List<Long> hashes);

更新

出于好奇,我写了自己的Iterable,并不是Collection看到方法失败。不出所料,Spring抛出

IllegalArgumentException:参数值 XXX 与预期类型不匹配 [java.lang.Long (n/a)]。

虽然它需要一个Long参数,但它运行良好Collection(我用过Arrays.asList(1L, 2L)),但执行一个愚蠢的 SQL 查询:

... from XXX XXX0_ where XXX0_.hash=(? , ?)
binding parameter [1] as [BIGINT] - [1]
binding parameter [2] as [BIGINT] - [2]

添加了findAllByHashIn,IN并且查询看起来不错:

... from XXX XXX0_ where XXX.hash in (? , ?)
binding parameter [1] as [BIGINT] - [1]
binding parameter [2] as [BIGINT] - [2]

推荐阅读