You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JPA派生查询硬编码枚举字段值失败,求确认查询规则

问题描述

我定义了如下实体:

public class Alert extends {
    @Column(name = "STATUS_CDE", nullable = false, length = 1)
    @Convert(converter = AlertStatusCodeTypeConverter.class)
    private AlertStatusCodeType statusCde;
}

statusCde是一个枚举字段:

public enum AlertStatusCodeType {

    INACTIVE("I"),
    ACTIVE("A");

    private String code;

    AlertStatusCodeType(String c) {
        this.code = c;
    }
}

数据库存读时,转换器负责将单字符String与枚举相互转换:

@Converter(autoApply = true)
public class AlertStatusCodeTypeConverter implements AttributeConverter<AlertStatusCodeType, String> {

    // 将枚举转换为存入数据库的值
    @Override
    public String convertToDatabaseColumn(AlertStatusCodeType alertStatusCodeType) {
        // 实现逻辑略
    }

    // 将数据库中的值转换为枚举
    @Override
    public AlertStatusCodeType convertToEntityAttribute(String code) {
        // 实现逻辑略
    }
}

我想编写JPA派生查询,筛选出ID在指定列表且状态为ACTIVE的Alert数据。如下查询方法可以正常工作:

List<Alert> findAllByIdInAndStatusCde(List<Long> ids, AlertStatusCodeType statusCode);

但我希望无需传入状态参数(直接筛选状态为'A'的数据),尝试编写如下方法时执行失败:

findAllByIdInAndStatusCdeActive(List<String> numbers)

报错信息:

No property active found for type AlertStatusCodeType! Traversed path: Alert.statusCde.

尝试CdeIsActive形式也无法成功。查阅Spring Data JPA文档后发现,仅isTrue这类isXXX关键词适用于布尔字段,请问是否确实如此?


解决方案

是的,Spring Data JPA的派生查询关键词中,isTrue/isFalse这类isXXX形式的关键词仅针对布尔类型字段,无法直接用于枚举类型来指定具体的枚举常量。针对你的需求,有两种简单可行的方案:

方案1:使用@Query注解编写JPQL查询

直接在查询方法上通过JPQL指定枚举常量,无需传入参数:

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;

public interface AlertRepository extends CrudRepository<Alert, Long> {

    @Query("SELECT a FROM Alert a WHERE a.id IN :ids AND a.statusCde = com.yourpackage.AlertStatusCodeType.ACTIVE")
    List<Alert> findAllByIdInAndActiveStatus(List<Long> ids);
}

注意替换com.yourpackage为你实际的枚举所在包路径。

方案2:编写默认方法调用原有查询

利用接口默认方法,封装原有查询并自动传入ACTIVE枚举值:

public interface AlertRepository extends CrudRepository<Alert, Long> {

    List<Alert> findAllByIdInAndStatusCde(List<Long> ids, AlertStatusCodeType statusCode);

    default List<Alert> findAllByIdInAndActiveStatus(List<Long> ids) {
        return findAllByIdInAndStatusCde(ids, AlertStatusCodeType.ACTIVE);
    }
}

这两种方案都能实现你无需手动传入状态参数、直接筛选ACTIVE状态数据的需求,其中方案2更简洁且复用了原有查询逻辑。


内容的提问来源于stack exchange,提问作者rhbc73

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 00:06:07