使用R2DBC保存实体时出现Long转Integer类型转换异常求助
问题场景
使用Spring Boot 2.7.9 + org.postgresql:r2dbc-postgresql 1.0.1.RELEASE,调用R2DBC的save方法更新实体时抛出类型转换异常,具体异常信息:
java.lang.ClassCastException: class java.lang.Long cannot be cast to class java.lang.Integer (java.lang.Long and java.lang.Integer are in module java.base of loader 'bootstrap')
at java.base/java.util.stream.Collectors.lambda$summingInt$19(Collectors.java:681)
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
业务代码如下:
override suspend fun save(entity: Entity): Entity = r2dbc.save(entity).awaitSingle()
实体类id字段类型为Long,数据库表id字段类型为bigint,无额外业务逻辑处理,推测异常发生在更新后实体解析阶段。
可能原因及解决办法
排查实体类非id字段的类型匹配
除id字段外,检查实体类中是否存在定义为Integer的字段,但对应数据库字段是bigint/numeric等返回Long类型的数值类型。比如计数类字段,数据库用bigint存储但实体类用Integer接收,会触发类型转换异常。需将实体类字段类型改为Long以匹配数据库类型。升级R2DBC PostgreSQL驱动版本
r2dbc-postgresql 1.0.1.RELEASE属于较旧版本,存在已知的类型转换bug。建议升级到兼容Spring Boot 2.7.9的稳定版本(如1.0.4.RELEASE),Spring Boot 2.7.x的依赖管理会自动适配对应版本范围,升级后多数类型转换问题可被修复。检查Spring Data R2DBC版本兼容
Spring Boot 2.7.9对应的Spring Data R2DBC版本为3.0.8,确认是否存在版本不兼容问题。可尝试升级至同大版本下的最新补丁版,修复内部聚合操作(如summingInt)的类型处理逻辑。手动指定字段类型映射
若升级版本无法解决,可在实体类字段上通过@Column注解明确指定SQL类型,确保类型映射准确:@Column(value = "id", type = SqlType.BIGINT) var id: Long? = null排查自定义Repository的聚合操作
若使用了自定义Repository实现,检查内部是否误用summingInt聚合方法处理Long类型的结果。需将这类操作替换为summingLong,避免强制类型转换。
内容的提问来源于stack exchange,提问作者agingcabbage32

