JPA Specification查询枚举时No enum constant异常如何解决
问题原因
OnboardingTaskStatus.valueOf() 方法要求传入的字符串必须和枚举常量名完全匹配(大小写敏感),如果传入的值不存在对应枚举常量,就会直接抛出IllegalArgumentException,你遇到的报错就是因为传入的status字符串找不到对应的枚举项。
解决方案
步骤1:给枚举类添加安全转换方法
在枚举类中新增自定义转换方法,捕获匹配失败的异常,兼容空格、大小写场景,转换失败直接返回null不抛出异常:
public enum OnboardingTaskStatus { NEW, IN_PROGRESS, DISABLED; // 安全转换方法,匹配失败返回null public static OnboardingTaskStatus parse(String statusStr) { if (statusStr == null) { return null; } try { // 先去除前后空格、转大写,实现大小写不敏感匹配 return OnboardingTaskStatus.valueOf(statusStr.trim().toUpperCase()); } catch (IllegalArgumentException e) { // 无匹配枚举项直接返回null,不向上抛异常 return null; } } }
步骤2:调整Specification查询逻辑
根据业务需求选择合适的无效值处理逻辑:
public Page<OnboardingTaskDto> findOnboardingTasks(OnboardingTaskSearchParams params, Pageable pageable){ Specification<OnboardingTasks> spec = (root, query, cb) -> { List<Predicate> predicates = new ArrayList<>(); if (params.getStatus() != null) { OnboardingTaskStatus statusEnum = OnboardingTaskStatus.parse(params.getStatus()); // 方案A:无效状态值忽略该过滤条件,返回其他条件匹配的所有结果 if (statusEnum != null) { predicates.add(cb.equal(root.get("status"), statusEnum)); } // 方案B:无效状态值直接返回空列表,适合参数校验失败返回无结果的业务场景 // if (statusEnum == null) { // predicates.add(cb.equal(cb.literal(1), 2)); // } else { // predicates.add(cb.equal(root.get("status"), statusEnum)); // } } return cb.and(predicates.toArray(new Predicate[0])); }; return onboardingTasksService.findAll(spec, pageable).map(onboardingMapper::taskToTaskDTO); }
内容的提问来源于stack exchange,提问作者Peter Penzov
相关产品推荐
相关产品推荐

