Spring Boot JPA-Hibernate连接Oracle 19g时出现数值溢出异常
Oracle 19g环境下Hibernate启动报数值溢出错误(Desbordamiento Numérico)
错误栈信息
Caused by: java.sql.SQLException: Desbordamiento Numérico at oracle.jdbc.driver.NumberCommonAccessor.throwOverflow(NumberCommonAccessor.java:4139) at oracle.jdbc.driver.NumberCommonAccessor.getLong(NumberCommonAccessor.java:636) at oracle.jdbc.driver.GeneratedStatement.getLong(GeneratedStatement.java:208) at oracle.jdbc.driver.GeneratedScrollableResultSet.getLong(GeneratedScrollableResultSet.java:261) at oracle.jdbc.driver.GeneratedResultSet.getLong(GeneratedResultSet.java:560) at com.zaxxer.hikari.pool.HikariProxyResultSet.getLong(HikariProxyResultSet.java) at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.resultSetMinValue(SequenceInformationExtractorLegacyImpl.java:115) at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.lambda$extractMetadata$0(SequenceInformationExtractorLegacyImpl.java:55) at org.hibernate.tool.schema.extract.spi.ExtractionContext.getQueryResults(ExtractionContext.java:50) at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.extractMetadata(SequenceInformationExtractorLegacyImpl.java:39) at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.initializeSequences(DatabaseInformationImpl.java:66) at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.<init>(DatabaseInformationImpl.java:60) at org.hibernate.tool.schema.internal.Helper.buildDatabaseInformation(Helper.java:183) ... 127 common frames omitted
已尝试操作
- 更换不同版本的Oracle JDBC驱动
- 切换多种Hibernate Oracle方言(OracleDialect、Oracle10gDialect、Oracle12cDialect、Oracle9iDialect)
- 注释
spring.datasource.driver-class-name和spring.jpa.database-platform配置项 - 手动执行Oracle生成的查询语句,结果正常
应用配置信息
# BBDD spring.datasource.driver-class-name=oracle.jdbc.OracleDriver #spring.datasource.url=jdbc:oracle:thin:@test:1521:orcl spring.datasource.url=jdbc:oracle:thin:@test:1521/orcl spring.datasource.username=TEST1 spring.datasource.password=TEST1 spring.jpa.database-platform=org.hibernate.dialect.OracleDialect #spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect #spring.jpa.database-platform=org.hibernate.dialect.Oracle12cDialect #spring.jpa.database-platform=org.hibernate.dialect.Oracle9iDialect spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update
实体类示例
@Entity public class Configuracion extends Base implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @NotNull @Length(max=32) private String clave; @NotNull @Length(max=512) private String valor; }
@Entity public class Callback extends Base implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String ine10; private String nombre; @NotNull private String org; @NotNull private String entity; @NotNull private String user; @Column(length = 2048) private String pass; @NotNull private String key; }
@Entity public class Entidad extends Base implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @NotNull @ManyToOne @JoinColumn private Entidad entidad; @NotNull @Length(max=12) private String aplicacion; @Length(max=24) private String origen; @Length(max=256) private String clave; @Lob private String peticion; @Lob private String respuesta; }
环境差异
- 本地Docker部署Oracle 21g:应用启动正常
- 客户环境Oracle 19g(19.0.0.0):启动失败,触发上述数值溢出错误
解决方案
该错误根源是Hibernate提取序列元数据时,尝试将Oracle序列的MINVALUE/MAXVALUE转换为Java Long类型,但Oracle默认序列的最大值(9999999999999999999999999999)远超出Long的取值范围(最大9223372036854775807),导致类型转换溢出。
方法1:使用适配Oracle 19c的Hibernate方言
确保Hibernate版本在5.4及以上,替换配置中的方言:
spring.jpa.database-platform=org.hibernate.dialect.Oracle19cDialect
Oracle19cDialect针对19g环境优化了序列元数据的提取逻辑。
方法2:禁用序列元数据提取
通过配置跳过Hibernate对序列MIN/MAX值的查询:
spring.jpa.properties.hibernate.schema_extract_sequence_metadata=false
方法3:显式指定序列生成策略
将实体类中的GenerationType.AUTO改为Oracle原生序列策略,明确指定序列名,减少Hibernate自动查询的范围:
@Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "configuracion_seq") @SequenceGenerator(name = "configuracion_seq", sequenceName = "CONFIGURACION_SEQ", allocationSize = 1) private Long id;
对所有实体类的ID字段执行相同修改。
方法4:调整Oracle序列范围
联系DBA将序列的MAXVALUE调整为Java Long能容纳的最大值:
ALTER SEQUENCE 目标序列名 MAXVALUE 9223372036854775807;
内容的提问来源于stack exchange,提问作者Jose Francisco Parra
相关产品推荐
相关产品推荐

