0

I want to create this Spring Data Repository:

Repository:

@Repository
public interface CustomersRepository extends JpaRepository<Users, Integer>, JpaSpecificationExecutor<Users> {

    Page<Users> findAllByTypeIn(Pageable page, String... types);

    Page<Users> findAllByTypeIn(Specification<Users> specification, Pageable pageable, List<String> types);
}

Service:

@Override
public Page<Users> findAll(int page, int size) {
    return dao.findAllByTypeIn(PageRequest.of(page, size), "CustomerUser");
}

@Override
public Page<Users> getAllBySpecification(Specification<Users> specification, Pageable pageable) {
    return this.dao.findAllByTypeIn(specification, pageable, List.of("CustomerUser"));
}

When I deploy the package I get this error:

Caused by: java.lang.IllegalStateException: Operator IN on type requires a Collection argument, found interface org.springframework.data.jpa.domain.Specification in method public abstract org.springframework.data.domain.Page org.engine.plugin.production.service.CustomersRepository.findAllByTypeIn(org.springframework.data.jpa.domain.Specification,org.springframework.data.domain.Pageable,java.util.List).

Do you know how this issue can be fixed?

Peter Penzov
  • 1,126
  • 134
  • 430
  • 808

1 Answers1

3

You can't use Specification with Spring data drived query in that way. You should use JpaSpecificationExecutor.

FindByTypeIn and methods like that define derived query, it means Spring Data JPA derived the query to be executed from the name of your method, this Capability provided to your CustomerRepository because you extended your repository from the JpaRepository, on the other hand findAll(Specification specification, Pagable pagable) came from another interface which is JpaSpecificationExecutor, its Ok to extend both of these Interfaces but it does not mean you can mix and match their Capability together:

So you Should define your repository like below and you should omit methods that contains Specification in their parameter because they came form JpaSpecificationExecutor

@Repository
public interface CustomerRepository extends JpaRepository<User, Integer>, JpaSpecificationExecutor<User> {
        
        Collection<User> findByTypeIn(Collection<String> types, Pageable pageable);
//      omit methods which have Specification here they are already defined in JpaSpecificationExecutor interface 
}

There is no problem in your situation because you can include your In operator inside Specification I don't elaborate more on how to do that because there is already a good answer here for this specific situation:

Add WHERE IN clause to JPA Specification

that link would solve your problem, however If you want to read more about JpaSpecificationExecutor you can read the following link for more detail:

spring data jpa specification

Tashkhisi
  • 2,070
  • 1
  • 7
  • 20