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

问题描述 投票:0回答:3

我正在使用 Spring Data JPA (4.3.5) 存储库和使用 IN 关键字子句并以

List<Enum>
字段作为参数的查询方法。问题是它没有按我的预期工作

给定一个像这样的实体:

@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);
}

当我运行(集成测试类)时:

List<Estat> estats = 
  Arrays.asList(Estat.VALIDA,Estat.PENDENT_DOCUMENTACIO,Estat.PENDENT_VALIDACIO);
List<cat.aoc.representa.domain.entity.representacio.Representacio> allByEstatIn = representacioRepository.findAllByEstatIn(estats);

生成的 SQL 是(在内存 H2 DB 中):

2018-08-01 12:30:48.534--ServerSession(1175154004)--Connection(384887832)--Thread(Thread[main,5,main])--SELECT UUID, .... FROM R_REPRESENTACIO WHERE (ESTAT IN ((?,?,?)))
    bind => [VALIDA, PENDENT_DOCUMENTACIO, PENDENT_VALIDACIO]

没有抛出 SQL 异常,返回零结果。 但这应该返回 1 个结果,因为(等效的)SQL 返回:

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

COUNT(*)
----------
         1

我能看到的独特区别是我如何将 IN 子句参数包装在 '' 之间(该列是 VARCHAR)。

我不知道为什么从 JPA 存储库生成的 SQL 没有返回结果。 (我也尝试过

findAllByEstatIsIn(List<Estat> estats)
,但返回了相同的零结果)。

有什么建议/解释吗?

PS:解决方法(不满意)使用

List<Representacio> findAllByEstatOrEstatOrEstat(Estat estat, Estat estat2, Estat estat3);

但这在很多方面都是丑陋且错误的......

java spring spring-data
3个回答
1
投票

使用 Spring Data 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);
}


0
投票

我建议使用类型为

List<String>
的参数并添加转换器
String -> Enum
,以便 Spring 能够对其进行转换。所以,基本上:

  1. List<Representacio> findByEstatIn(List<String> estats);
  2. 2.
@Configuration
public class ConverterConfiguration extends RepositoryRestConfigurerAdapter {
  @Autowired
  private EstatsConverter estatsConverter;

  @Override
  public void configureConversionService(ConfigurableConversionService conversionService) {
    conversionService.addConverter(estatsConverter);

    super.configureConversionService(conversionService);
  }
    3.
@Component
public class EstatsConverter implements Converter<String, Estat> {

    @Override
    public Estat convert(String source) {
        return Estat.fromString(source);
    }
}

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


0
投票

我也遇到这个问题了。我找到了here并希望将其写为答案。我希望,它可以节省某人宝贵的时间。

示例代码如下:

@Query(nativeQuery = true, 
       value = "SELECT * FROM articles 
              WHERE stage IN (:#{#stages.![name()]})")
List<Article> getByStageIn(@Param("stages") List<ArticleStage> stages);
© www.soinside.com 2019 - 2024. All rights reserved.