Java执行SQL查询无小数但数据库端执行返回小数问题排查
问题排查与修复方案
1. 最可能的根因:Hibernate原生SQL未显式指定返回字段类型,类型转换时丢失小数
当前的原生SQL查询没有显式声明total_recaudado的返回类型,Hibernate会自动根据数据库元数据推断返回类型,若推断为Long/Integer等整数类型,反射赋值给double属性时会直接丢弃小数部分,仅保留整数位。
修复方式:创建SQLQuery后,显式指定返回字段的类型和别名即可:
SQLQuery querySQL = getHibernateTemplate().getSessionFactory().getCurrentSession() .createSQLQuery(query.toString()); // 新增此行显式指定字段别名和对应的Double类型 querySQL.addScalar("total_recaudado", DoubleType.INSTANCE); querySQL.setResultTransformer(Transformers.aliasToBean(DatosEstadistica.class));
低版本Hibernate可使用Hibernate.DOUBLE替代DoubleType.INSTANCE
2. 次优先级排查:别名大小写不匹配
SQL中字段别名是小写的total_recaudado,但实体类的属性是全大写的TOTAL_RECAUDADO,Transformers.aliasToBean默认大小写敏感,可能出现赋值异常。
修复方式二选一:
- 将SQL中的别名改为全大写:
as TOTAL_RECAUDADO - 将实体类的属性、get/set方法命名改为和SQL别名一致
3. 可选优化:将实体类属性改为包装类Double
基本类型double默认值为0.0,若查询返回null会触发空指针异常,改为包装类Double更安全,也能避免部分自动装箱拆箱导致的精度丢失问题:
private Double TOTAL_RECAUDADO; public Double getTOTAL_RECAUDADO() { return TOTAL_RECAUDADO; } public void setTOTAL_RECAUDADO(Double tOTAL_RECAUDADO) { TOTAL_RECAUDADO = tOTAL_RECAUDADO; }
4. 快速验证手段
可在DAO层先移除setResultTransformer配置,直接打印querySQL.list()的原始返回结果,查看每个元素的数据类型和实际值,就能快速定位是类型转换问题还是映射问题。
内容的提问来源于stack exchange,提问作者Imrik
相关产品推荐
相关产品推荐

