Hibernate中调整group by后NativeQuery查询返回类型不一致问题
问题原因说明
根本原因
- MySQL驱动的返回类型受查询语法影响:该问题场景中year、monthOfYear字段的返回类型变化,本质是不同分组规则下,这两个字段在SQL中的计算逻辑不同导致的。当分组规则包含year、monthOfYear时,这两个字段是直接读取原始表的INT类型列,JDBC驱动会直接映射为Integer类型;当仅按customerId分组时,受MySQL
ONLY_FULL_GROUP_BY模式限制,select中的year、monthOfYear必须包裹聚合函数(如MAX、MIN),而MySQL数值聚合函数的默认返回类型为BIGINT,对应JDBC驱动就会映射为BigInteger类型。 - Hibernate 5.4.x版本存在已知特性限制:问题中尝试的
@ColumnResult(type = int.class)配置不生效,是因为Hibernate 5.4版本中,ConstructorResult对原生查询的类型转换支持不完善,该属性仅会做类型匹配校验,不会主动执行跨数字类型的转换,该问题在Hibernate 6.x及以上版本已修复。
可行解决方案
- 方案1:改造原生SQL,对聚合后的字段显式指定类型:对需要包裹聚合函数的year、monthOfYear字段,使用
CAST强制转换为INT类型,示例:CAST(MAX(year) AS SIGNED INTEGER) AS year,即可强制JDBC返回Integer类型。 - 方案2:兼容不同数字类型:将投影类构造函数的year、monthOfYear入参改为
Number类型,在构造函数内部调用intValue()方法转换为int,可同时兼容Integer、BigInteger两种返回类型,示例代码:
public MonthlySalesProjection(String segment, String businessArea, int customerId, int customerGroupId, String category, String manufacturer, String organizationNumber, Number year, Number monthOfYear, BigDecimal totalSales, BigDecimal totalVAT, BigDecimal tb, BigDecimal quantity) { // 其余字段赋值逻辑保持不变 this.year = year.intValue(); this.monthOfYear = monthOfYear.intValue(); }
- 方案3:升级Hibernate版本到6.x,该版本已修复
@ColumnResult指定type不生效的问题,配置后可自动完成类型转换。
内容的提问来源于stack exchange,提问作者Staffan Runnsjö
相关产品推荐
相关产品推荐

