JPA Criteria查询LocalDateTime字段参数类型不匹配异常修复
问题原因
该异常由JPA Criteria查询的参数类型不匹配导致:
- Controller层通过
@RequestParam接收到的value参数是String类型,传入Service层时未做任何类型转换 - 实体类中
dateTimeAppointment字段的类型为java.time.LocalDateTime,criteriaBuilder.equal()构建查询条件时,要求传入的参数类型与对应字段类型一致,JPA不会自动完成字符串到LocalDateTime的类型转换 - 实体字段上的
@JsonFormat注解仅在JSON序列化/反序列化阶段生效,对JPA查询的参数转换逻辑无任何作用。
修复方案
修复核心是:构建查询条件前,根据查询字段的实际类型,将传入的字符串参数转换为匹配的Java类型,再传入equal()方法。
修改后的CriteriaService代码如下:
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; public class CriteriaService { // 日期格式与实体类@JsonFormat中定义的格式保持一致 private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd,HH:mm"); @PersistenceContext private EntityManager entityManager; public List<Client> getClientByParam(String name, String value) { CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<Client> criteriaQuery = criteriaBuilder.createQuery(Client.class); Root<Client> root = criteriaQuery.from(Client.class); // 按目标字段类型转换参数值 Object queryParam; if ("dateTimeAppointment".equals(name)) { queryParam = LocalDateTime.parse(value, DATETIME_FORMATTER); } else { // 字符串类型字段直接使用原值,后续新增其他类型字段可在此扩展转换分支 queryParam = value; } Predicate predicate = criteriaBuilder.equal(root.get(name), queryParam); criteriaQuery.where(predicate); return entityManager.createQuery(criteriaQuery).getResultList(); } }
- 若后续需要支持更多字段类型的动态查询(如Integer、LocalDate等),可在参数转换的分支中补充对应类型的解析逻辑,保证传入查询条件的参数类型与实体字段类型一致即可。
- 可在日期解析位置增加参数格式校验和异常捕获,当传入的时间格式不符合要求时返回明确的错误提示,避免直接抛出服务端异常。
内容的提问来源于stack exchange,提问作者Kirill_Yudaev
相关产品推荐
相关产品推荐

