Java 使用枚举列表作为参数的IN关键字的Spring数据查询方法

Java 使用枚举列表作为参数的IN关键字的Spring数据查询方法,java,spring,spring-data,Java,Spring,Spring Data,我正在使用一个SpringDataJPA(4.3.5)存储库和一个查询方法,该方法使用IN关键字子句,并将列表字段作为参数。问题是它没有像我预期的那样工作 给定如下实体: @Entity @Table(name = "R_REPRESENTACIO") public class Representacio { @Enumerated(EnumType.STRING) private Estat estat; ... //getters and sette

我正在使用一个SpringDataJPA(4.3.5)存储库和一个查询方法,该方法使用IN关键字子句,并将
列表
字段作为参数。问题是它没有像我预期的那样工作

给定如下实体:

@Entity
@Table(name = "R_REPRESENTACIO")
public class Representacio {

    @Enumerated(EnumType.STRING)
    private Estat estat;   

    ...
    //getters and setters
    ...
}
使用该SQL声明:

CREATE TABLE R_REPRESENTACIO (
  UUID NUMBER(19) NOT NULL,
  ...
  ESTAT VARCHAR2(255) NULL,
  ...
);
Estat
是一个枚举类,类似于:

public enum Estat {
        VALIDA,
        PENDENT_VALIDACIO,
        PENDENT_DOCUMENTACIO,
        ...
}
和JPA存储库,如:

public interface RepresentacioRepository extends JpaRepository<Representacio, Long> {
    List<Representacio> findAllByEstatIn(List<Estat> estats);
}
不会引发任何SQL异常,并且不会返回任何结果。 但这应该返回1个结果,因为此(等效)SQL返回:

SELECT count(*) FROM R_REPRESENTACIO WHERE ESTAT IN ('VALIDA','PENDENT_DOCUMENTACIO','PENDENT_VALIDACIO');

COUNT(*)
----------
         1
我能看到的唯一区别是如何在“”之间包装IN子句参数(该列是一个VARCHAR)

我不知道为什么从JPA存储库生成的SQL没有返回结果。 (我还尝试了
findallbystatisin(List estats)
,返回了相同的零结果)

有什么建议/解释吗

PS:变通(不满意)使用

列出findallbyestatrestater(Estat-Estat、Estat-estat2、Estat-estat3);

但这在很多方面都是丑陋和错误的…

我建议使用类型为
List
的参数,并添加转换器
String->Enum
,这样Spring就可以转换它了。因此,基本上:

  • List findByEstatIn(List estats)
  • 2.
    @配置
    公共类转换器配置扩展了RepositoryRestConfigurerAdapter{
    @自动连线
    私人房地产转换人房地产转换人;
    @凌驾
    公共void配置转换服务(ConfigurableConversionService转换服务){
    conversionService.addConverter(EstatConverter);
    super.configureConversionService(conversionService);
    }
    
    3.
    @组件
    公共类EstatConverter实现转换器{
    @凌驾
    公共资产转换(字符串源){
    返回Estat.fromString(源);
    }
    }
    

    我不知道这是否可行,但我记得我做过类似的事情,只是在MongoDB中。如果您尝试过,请告诉我。

    使用spring数据JPA和JPQL非常简单:

    @Repository
    public interface RepresentacioRepository extends JpaRepository<Representacio, Long> {
    
        @Query("select r from Representacio r where r.estat in :estat2")
        List<Representacio> findByEnumEstat(@Param("estat2") List<Estat> estatList);
    }
    
    
    @存储库
    公共接口RepresentationRepository扩展了JpaRepository{
    @查询(“从Representacio r中选择r,其中r.estat in:estat2”)
    List findByEnumEstat(@Param(“estat2”)List estatList);
    }
    
    如您所述,
    @Enumerated(EnumType.STRING)
    列是varchar,但您的参数是一个枚举列表。您是否尝试过使用字符串列表?是的,尝试了类似FindAllByestin(List estats)的存储库方法,并运行repo.FindAllByestin(Arrays.asList(“VALIDA”,“PENDENT\u VALIDACIO”…)但是抛出java.lang.ClassCastException:java.lang.String不能被强制转换为java.lang.Enum您是否尝试过自己编写一个查询?
    @query(“从Representacio r中选择r,其中r.estat位于:estats”)
    如果您跳过“全部”并使用
    列表findByEstatIn(列表estat)会怎么样
    ?@mrkernelpanic我希望了解IN子句的工作原理和方式,并尽可能避免编写sql,但在这种情况下,您的解决方案很简单,正如我所期望的那样工作。您的解决方案很好!我喜欢您的aproach,但我使用的不是REST存储库,而是JpaRepository,无法使用RepositoryRestConfigurerAdapter类。我一直在寻找或者JpaReposotory的类似解决方案,但我不知道如何…我想知道IN子句为什么或如何在具有枚举列表的查询方法中工作,但正如@mrkernelpanic在问题中所评论的,此解决方案解决了muy用例
    SELECT count(*) FROM R_REPRESENTACIO WHERE ESTAT IN ('VALIDA','PENDENT_DOCUMENTACIO','PENDENT_VALIDACIO');
    
    COUNT(*)
    ----------
             1
    
    List<Representacio> findAllByEstatOrEstatOrEstat(Estat estat, Estat estat2, Estat estat3);
    
    @Repository
    public interface RepresentacioRepository extends JpaRepository<Representacio, Long> {
    
        @Query("select r from Representacio r where r.estat in :estat2")
        List<Representacio> findByEnumEstat(@Param("estat2") List<Estat> estatList);
    }