IllegalStateException: 类型上的运算符IN需要一个集合参数

huangapple go评论79阅读模式
英文:

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&lt;Users, Integer&gt;, JpaSpecificationExecutor&lt;Users&gt; {
Page&lt;Users&gt; findAllByTypeIn(Pageable page, String... types);
Page&lt;Users&gt; findAllByTypeIn(Specification&lt;Users&gt; specification, Pageable pageable, List&lt;String&gt; types);
}

Service:

@Override
public Page&lt;Users&gt; findAll(int page, int size) {
return dao.findAllByTypeIn(PageRequest.of(page, size), &quot;CustomerUser&quot;);
}
@Override
public Page&lt;Users&gt; getAllBySpecification(Specification&lt;Users&gt; specification, Pageable pageable) {
return this.dao.findAllByTypeIn(specification, pageable, List.of(&quot;CustomerUser&quot;));
}

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,你可以阅读下面的链接获取更多细节:

spring data jpa specification

英文:

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&lt;User, Integer&gt;, JpaSpecificationExecutor&lt;User&gt; {
Collection&lt;User&gt; findByTypeIn(Collection&lt;String&gt; 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:

spring data jpa specification

huangapple
  • 本文由 发表于 2020年10月20日 04:11:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/64434497.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定