简体   繁体   中英

Spring data findAllBy with iterable returns empty array

Using a ReactiveMongoRepository and a custom method to return all objects with the matching property is returning a empty collection on anything other than the findAllById call.

I'm wondering if I just misunderstood something here and this only works on the ID field or something?

The interface I'm using:

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

And I'm just calling that via:

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

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

    return videoRepository.findAllByHash(hashList);
}

For reference, the POJO in question:

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

    @Id
    String id;

    long hash;

    //{...}
}

I have confirmed I'm passing in three values in the hashList which match the custom hash property set on the Video POJO.

Should this not return all Video objects which have the matching custom hash property as it does when I do the same thing but for the id property?

findAllByHashIn(Collection<Long> hashes);

I've never used an Iterable as a parameter to a custom JPA repository method before, but I would translate the name findAllByHash as "take a single hash value and find all entries possessing that value" and the signature would be findAllByHash(Long hash) .

Your motivation is a bit different: you want all hashes to be used during the search. According to this table ,

Keyword | Sample                             | JPQL snippet

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

Spring JPA support logical IN and accepts a subclass of Collection , so it could be

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

Update

Out of curiosity, I wrote own Iterable which isn't a Collection to see the method fail. As expected, Spring threw

IllegalArgumentException: Parameter value XXX did not match expected type [java.lang.Long (n/a)].

Although it expects a Long parameter, it runs well with a Collection (I used Arrays.asList(1L, 2L) ), but executes a silly SQL query:

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

With findAllByHashIn , IN is added and the query looks nice:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM