SpringBoot原生查询中Enum类型jdbcMapping为空映射错误排查
问题解决:原生SQL查询中Enum类型映射失败的报错处理
问题原因
使用原生SQL查询时,JPA的@Enumerated注解配置不会生效,Hibernate无法自动将PatientTypeEnum枚举对象转换为数据库中存储的字符串值,导致出现jdbcMapping为null的参数绑定错误。
解决方案
方案1:传递枚举的code值(推荐)
直接在查询中使用枚举的code属性值,而非枚举对象本身,有两种实现方式:
方式A:修改方法参数为String,调用时传入code
调整Repository查询方法:
@Transactional @Query(value="SELECT * FROM tb_patient o WHERE o.patientId = :patientId AND o.patientType = :patientTypeCode AND o.deletedAt Is Null AND o.deletedBy Is Null AND o.deletedByUserType Is Null ", nativeQuery = true) List<PatientInsurance> findCustomQuery(@Param("patientId")String patientId, @Param("patientTypeCode")String patientTypeCode);
调用时传入枚举的code值:
patientInsuranceRepository.findCustomQuery("123", PatientTypeEnum.OPG.getCode());
方式B:使用SpEL表达式直接获取枚举的code
无需修改方法参数,在原生SQL参数中通过SpEL访问枚举的code属性:
@Transactional @Query(value="SELECT * FROM tb_patient o WHERE o.patientId = :patientId AND o.patientType = :#{#patientType.code} AND o.deletedAt Is Null AND o.deletedBy Is Null AND o.deletedByUserType Is Null ", nativeQuery = true) List<PatientInsurance> findCustomQuery(@Param("patientId")String patientId, @Param("patientType")PatientTypeEnum patientType);
方案2:改用HQL查询
如果业务允许,放弃原生SQL,使用HQL让Hibernate自动处理枚举映射:
@Transactional @Query("SELECT o FROM PatientInsurance o WHERE o.patientId = :patientId AND o.patientType = :patientType AND o.deletedAt Is Null AND o.deletedBy Is Null AND o.deletedByUserType Is Null ") List<PatientInsurance> findCustomQuery(@Param("patientId")String patientId, @Param("patientType")PatientTypeEnum patientType);
方案3:自定义Hibernate类型映射(复杂场景)
如果需要在多个原生SQL查询中复用枚举映射,可以自定义Hibernate类型适配器,但该方式相对繁琐,一般前两种方案足以解决问题。
关键说明
- 原生SQL直接与数据库交互,绕过JPA的ORM映射逻辑,因此
@Enumerated注解的配置对原生SQL无效。 - HQL由Hibernate解析,会自动根据
@Enumerated(EnumType.STRING)的配置将枚举转换为对应字符串值,无需手动处理。
内容的提问来源于stack exchange,提问作者dracile
相关产品推荐
相关产品推荐

