You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

传递枚举作为查询参数时触发十六进制字符异常求助

解决H2数据库中枚举参数传入原生SQL查询的报错问题

问题分析

报错Caused by: org.h2.jdbc.JdbcSQLDataException: Hexadecimal string contains non-hex character: "SWEDISH_MARKET"的核心原因有两个:

  1. 参数名不匹配:DAO方法中@Param("licenseMarket")定义的参数名,与SQL语句里的:market不一致,导致参数未正确绑定,H2错误解析枚举类型。
  2. H2与PostgreSQL的枚举处理差异:PostgreSQL支持cast :market as text将枚举转为字符串,但H2对原生SQL中的枚举参数默认解析逻辑不同,会将枚举实例错误识别为二进制/十六进制类型。

解决方案

步骤1:修正参数名匹配问题

先确保DAO方法的@Param参数名与SQL中的占位符完全一致,二选一修改即可:

  • 方式A:修改SQL占位符
@Query(value = "SELECT count(*) " + 
                "FROM Statements statements WHERE " +
                "market = :licenseMarket",
            nativeQuery = true)
long countStatements(@Param("licenseMarket") Market market);
  • 方式B:修改@Param参数名
@Query(value = "SELECT count(*) " + 
                "FROM Statements statements WHERE " +
                "market = :market",
            nativeQuery = true)
long countStatements(@Param("market") Market market);

步骤2:兼容H2的枚举参数处理

修正参数名后,还需让H2正确识别枚举的字符串值,推荐两种通用方案:

方案一:直接传入枚举的字符串名称

修改方法参数为String,调用时传入枚举的name()值:

@Query(value = "SELECT count(*) FROM Statements statements WHERE market = :market", nativeQuery = true)
long countStatements(@Param("market") String market);

// 调用示例
countStatements(Market.SWEDISH_MARKET.name());
方案二:使用Spring Data SpEL表达式获取枚举名称

保持参数为枚举类型,通过SpEL表达式在原生SQL中直接提取枚举的字符串值,兼容PostgreSQL和H2:

@Query(value = "SELECT count(*) FROM Statements statements WHERE market = :#{#market.name()}", nativeQuery = true)
long countStatements(@Param("market") Market market);

// 调用方式不变
countStatements(Market.SWEDISH_MARKET);

注意事项

  • 避免在H2中使用PostgreSQL的cast :market as text语法,H2对枚举类型的CAST逻辑不兼容该写法。
  • 若使用H2的内存数据库做测试,需确保实体类的@Enumerated(EnumType.STRING)注解配置正确,与数据库字段类型(VARCHAR)匹配。

内容的提问来源于stack exchange,提问作者user9304291

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 13:40:25