Spring 数据 findAllBy 可迭代 returns 空数组

Spring data findAllBy with iterable returns empty array

使用 ReactiveMongoRepository 和自定义方法 return 所有具有匹配 属性 的对象 return 在 [=16 以外的任何对象上创建一个空集合=] 打电话。

我想知道我是否只是误解了这里的内容,这只适用于 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;

    //{...}
}

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

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

findAllByHashIn(Collection<Long> hashes);

我以前从未使用过 Iterable 作为自定义 JPA 存储库方法的参数,但我会将名称 findAllByHash 翻译为 "take a single hash value and find all entries possessing that value" 并且签名将是 findAllByHash(Long hash).

您的动机有点不同:您希望在搜索过程中使用所有散列。根据this table

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: Parameter value XXX did not match expected type [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]