问题描述
我想创建这个Spring Data 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);
}
服务:
@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"));
}
当我部署软件包时,出现此错误:
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).
您知道如何解决此问题吗?
解决方法
您不能以这种方式将Specification
用于Spring数据驱动的查询。您应该使用JpaSpecificationExecutor
。
FindByTypeIn
和类似的方法定义了派生查询,这意味着Spring Data JPA派生了要从您的方法名称执行的查询,此功能提供给您的CustomerRepository
,因为您从JpaRepository
,另一方面,findAll(Specification specification,Pagable pagable)
来自另一个接口JpaSpecificationExecutor
,可以扩展这两个接口,但这并不意味着您可以将其功能混合使用或匹配:
因此,您应该像下面那样定义存储库,并且应该省略在其参数中包含规范的方法,因为它们来自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
}
您的情况没有问题,因为您可以将In
运算符包含在Specification
中,因此我不会详细说明如何执行此操作,因为在此情况下已经有了很好的答案:
Add WHERE IN clause to JPA Specification
该链接可以解决您的问题,但是,如果您想详细了解JpaSpecificationExecutor
,可以阅读以下链接以获取更多详细信息: