Spring JPA Specification复杂枚举映射模糊查询异常解决
解决Spring JPA Specification枚举模糊查询类型不匹配问题
出现该异常的核心原因是:JPA默认会将枚举属性当作CoApplicationType类型处理,但模糊查询传入的是字符串参数,类型不匹配导致报错。以下是两种可行的解决方法:
方法一:直接操作数据库字段(推荐)
利用AttributeConverter已将枚举转换为CHAR类型存储的特性,在Specification中把枚举属性转换为字符串类型后执行LIKE查询,绕过枚举类型校验:
public static Specification<CoDocument> applicationTypeLike(String keyword) { return (root, query, criteriaBuilder) -> { // 将枚举属性转为字符串类型,直接对数据库存储的CHAR值做模糊匹配 return criteriaBuilder.like( root.get("coApplicationType").as(String.class), "%" + keyword + "%" ); }; }
关键点说明
root.get("coApplicationType")指向实体类的枚举属性,JPA会自动关联到数据库对应的CHAR字段as(String.class)强制将枚举属性转换为数据库存储的字符串类型,确保和传入的%ASE%参数类型匹配
方法二:先筛选匹配的枚举再查询
如果需要基于枚举的自定义属性做匹配,可先通过关键字筛选出符合条件的枚举实例,再用IN查询替代LIKE:
// 第一步:根据关键字筛选匹配的枚举 List<CoApplicationType> matchedTypes = Arrays.stream(CoApplicationType.values()) .filter(type -> type.getCustomAttr().contains(keyword)) // 替换为你的枚举自定义属性方法 .collect(Collectors.toList()); // 第二步:用Specification构建IN查询 public static Specification<CoDocument> applicationTypeIn(List<CoApplicationType> types) { return (root, query, criteriaBuilder) -> root.get("coApplicationType").in(types); }
适用场景
这种方式适合枚举的自定义属性与数据库存储值一一对应的场景,若存储值和自定义属性不一致,还是推荐用方法一。
补充:用@Query注解实现相同效果
如果不想用Specification,也可以直接通过JPQL注解实现,原理和方法一一致:
@Query("SELECT d FROM CoDocument d WHERE CAST(d.coApplicationType AS string) LIKE %:keyword%") List<CoDocument> findByApplicationTypeLike(@Param("keyword") String keyword);
内容的提问来源于stack exchange,提问作者hum_ChrisWU
相关产品推荐
相关产品推荐

