Spring JPA原生查询触发Hibernate报错:Ordinal parameter label was not an integer 求助
兄弟,我之前也踩过类似的坑,咱们来一步步拆解这个问题:
首先看你遇到的报错org.hibernate.QueryException: Ordinal parameter label was not an integer,本质原因是Hibernate在处理原生SQL的位置参数(?1、?2)时,和枚举类型的参数绑定逻辑发生了冲突。你的DayOfWeek是枚举类型,实体里又标注了@Enumerated(EnumType.STRING)(数据库里存的是MONDAY这类字符串值),但用位置参数时,Hibernate没法正确把枚举对象转换成数据库能识别的字符串格式,反而在参数解析环节出了问题。
给你两个靠谱的解决方案:
方案一:改用命名参数(推荐)
位置参数在原生查询里和枚举搭配容易出问题,换成命名参数不仅能解决报错,代码可读性也更强:
修改你的Repository方法:
@Repository public interface CleanerRepository extends JpaRepository<Cleaner, Integer> { @Query(value = "SELECT * FROM cleaner clnr JOIN cleaner_schedule_record csr on clnr.cleaner_id = csr.cleaner_cleaner_id" + " WHERE csr.week_day=:day AND csr.floor_number=:floorNumber;", nativeQuery = true) Optional<Cleaner> findCleanerByFloorAndDay(@Param("day") DayOfWeek day, @Param("floorNumber") Integer floorNumber); }
调用的时候还是用原来的写法findCleanerByFloorAndDay(DayOfWeek.MONDAY, 3)就行,Hibernate会自动把枚举转换成对应的字符串值绑定到命名参数上。
方案二:手动转换枚举为字符串
如果你不想改动参数形式,也可以在调用方法时直接把枚举转成字符串传入:
findCleanerByFloorAndDay(DayOfWeek.MONDAY.name(), 3);
同时记得修改Repository方法的参数类型:
Optional<Cleaner> findCleanerByFloorAndDay(String day, Integer floorNumber);
这种方式绕开了Hibernate的枚举自动转换逻辑,直接传入数据库存储的字符串值,也能解决问题。
最后补充检查点:确认你的cleaner_schedule_record表中week_day字段是VARCHAR类型,和实体里的EnumType.STRING对应,如果是整数类型的话,需要把实体枚举注解改成@Enumerated(EnumType.ORDINAL),不过看你的报错应该不是这个问题。
备注:内容来源于stack exchange,提问作者Serhii Chernikov

