英文:
IllegalStateException: Operator IN on type requires a Collection argument
问题
我想创建这个 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"));
}
在部署包时我遇到了这个错误:
Caused by: java.lang.IllegalStateException: 对类型的 IN 操作需要一个集合参数,在方法 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) 中找到了 interface org.springframework.data.jpa.domain.Specification。
您知道如何解决这个问题吗?
英文:
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?
答案1
得分: 3
你不能以那种方式在 Spring 数据派生查询中使用 Specification
。你应该使用 JpaSpecificationExecutor
。
FindByTypeIn
和类似的方法定义了派生查询,这意味着 Spring Data JPA 根据方法名派生出要执行的查询。这个能力是因为你的 CustomerRepository
扩展了 JpaRepository
。另一方面,findAll(Specification specification, Pagable pagable)
方法来自另一个接口,即 JpaSpecificationExecutor
,虽然你可以同时扩展这两个接口,但并不意味着你可以混合使用它们的能力:
因此,你应该像下面这样定义你的 repository,并且应该省略那些参数中包含 Specification 的方法,因为它们已经在 JpaSpecificationExecutor
接口中定义过了:
@Repository
public interface CustomerRepository extends JpaRepository<User, Integer>, JpaSpecificationExecutor<User> {
Collection<User> findByTypeIn(Collection<String> types, Pageable pageable);
// 省略那些在 JpaSpecificationExecutor 接口中已经定义的带有 Specification 的方法
}
在你的情况下没有问题,因为你可以在 Specification
内部使用你的 In
操作符。关于如何做到这一点,我不再详细展开,因为在这个特定情况下已经有了一个很好的答案,你可以在这个链接中找到解决方案:
https://stackoverflow.com/questions/56959816/add-where-in-clause-to-jpa-specification
如果你想更多地了解 JpaSpecificationExecutor
,你可以阅读下面的链接获取更多细节:
英文:
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:
https://stackoverflow.com/questions/56959816/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:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论