Blazebit中BigDecimal转Long类型转换异常排查求助
排查BigDecimal转Long的ClassCastException问题(Blazebit+Deltaspike+Oracle)
在Jakarta EE项目中使用Blazebit、Deltaspike和Oracle数据库时,调用带Specification的findAll查询触发java.lang.ClassCastException: java.math.BigDecimal cannot be cast to java.lang.Long,异常堆栈指向Blazebit的PaginatedTypedQueryImpl.getResultList方法。
核心原因
该异常本质是JDBC查询返回的BigDecimal类型值被强制转换为Long类型,通常由以下场景导致:
- 实体类字段类型与数据库字段的JDBC映射不匹配
- Blazebit实体视图的字段类型与实体类/数据库类型不一致
- 查询构建(Specification)时使用了错误的类型匹配
具体排查步骤
1. 检查实体类与数据库字段的类型映射
查看PRODUCTOFINANCIERO和DETALLEPRODUCTOFINANCIERO对应的实体类:
- 主键字段(如
productoFinancieroId)若在实体类中定义为Long,但Oracle的NUMBER(19)类型在JDBC驱动中默认返回BigDecimal,会直接触发强制转换失败。 - 解决方案:将实体类主键字段改为
BigInteger或BigDecimal,或通过JPA注解指定类型映射(以Hibernate为例):
@Id @Column(name = "PRODUCTOFINANCIEROID", columnDefinition = "NUMBER(19)") @Type(type = "long") private Long productoFinancieroId;
2. 验证Blazebit实体视图的类型一致性
如果使用了Blazebit Entity View:
- 确保视图中对应的ID字段或数值字段类型与实体类完全一致,比如实体类用
BigDecimal,视图不能用Long。 - 检查视图定义的字段映射规则,避免类型不匹配导致转换错误。
3. 排查Specification的构建逻辑
查看ConsultaProductoServiceImpl.consulta方法中构建Specification的代码:
- 确认所有条件判断的参数类型与实体类字段类型匹配,不要用
Long类型参数匹配实体类中BigDecimal类型的字段(如tipoMonedaId等)。 - 错误示例与修正:
// 错误:参数类型Long与字段类型BigDecimal不匹配 cb.equal(root.get("tipoMonedaId"), 1L); // 正确:参数类型与字段类型一致 cb.equal(root.get("tipoMonedaId"), BigDecimal.valueOf(1));
4. 检查JPA提供者的配置
针对Hibernate等JPA提供者:
- 确保使用正确的Oracle方言(如
org.hibernate.dialect.Oracle12cDialect),不同方言对数值类型的映射逻辑不同。 - 可添加配置参数强制数值类型转换,在
persistence.xml中配置:
<property name="hibernate.type.preferred_integer_type" value="java.lang.Long"/>
内容的提问来源于stack exchange,提问作者Jose Amadeo Diaz Diaz
相关产品推荐
相关产品推荐

