Grails4+Hibernate5升级SqlServer2012SpatialDialect遇类型转换错误求助
问题描述
当前项目application.yml中Hibernate方言配置如下:
dataSource: pooled: true jmxExport: true driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver dialect: org.hibernate.spatial.dialect.sqlserver.SqlServer2008SpatialDialect
该配置运行正常,但因部分实体类需映射SQL Sequences,需将方言升级为SqlServer2012SpatialDialect。测试多个hibernate-spatial 5.*版本搭配该方言时,均抛出如下类型转换错误:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibernateDatastore': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.grails.orm.hibernate.HibernateDatastore]: Constructor threw exception; nested exception is java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.Long (java.lang.Integer and java.lang.Long are in module java.base of loader 'bootstrap') ... Caused by: java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.Long (java.lang.Integer and java.lang.Long are in module java.base of loader 'bootstrap') at com.microsoft.sqlserver.jdbc.SQLServerResultSet.getLong(SQLServerResultSet.java:2328) at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.resultSetStartValueSize(SequenceInformationExtractorLegacyImpl.java:129)
环境信息:
- SQL Server:Microsoft SQL Server 2019
- Gradle依赖:
com.microsoft.sqlserver:mssql-jdbc:12.2.0.jre11 - Grails版本:4.x
原因分析
错误根源是Hibernate默认的SequenceInformationExtractorLegacyImpl提取SQL Server序列的start_value时,强制调用getLong()方法,但SQL Server中该字段实际为int类型,JDBC驱动返回Integer对象,强转Long时触发类型转换异常。
解决方法
方法一:自定义方言替换Sequence信息提取器
创建自定义方言类,继承SqlServer2012SpatialDialect,重写序列信息提取逻辑,使用SQL Server专属的提取器:
import org.hibernate.spatial.dialect.sqlserver.SqlServer2012SpatialDialect; import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractor; import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorSQLServerImpl; public class CustomSqlServer2012SpatialDialect extends SqlServer2012SpatialDialect { @Override public SequenceInformationExtractor getSequenceInformationExtractor() { return SequenceInformationExtractorSQLServerImpl.INSTANCE; } }
修改application.yml配置使用自定义方言:
dataSource: # 其他原有配置... dialect: com.yourpackage.CustomSqlServer2012SpatialDialect
方法二:检查实体类Sequence映射配置
确保实体类中@SequenceGenerator的配置匹配SQL Server序列特性:
- 确认
startValue设置符合SQL Server序列的数值类型(默认int范围即可,无需设置过大的Long类型值) - 保证
allocationSize与数据库序列的INCREMENT BY值一致,避免Hibernate与数据库序列步长不匹配
方法三:升级hibernate-spatial版本
尝试升级到hibernate-spatial 5.6.x及以上版本,新版本已修复该类型转换问题,且兼容Grails 4.x对Hibernate 5.4+的要求。
内容的提问来源于stack exchange,提问作者lujjas
相关产品推荐
相关产品推荐

