Java SequenceInformation提取器RacledatabaseImpl{ 公共静态最终SequenceInformationExtractor实例=新SequenceInformationExtractor(); 私有静态最终BigDecimal LONG\u MIN\u VALUE\u作为\u DECIMAL=BigDecimal.valueOf(LONG.MIN\u VALUE); 私有静态最终BigDecimal LONG\u MAX\u VALUE\u作为\u DECIMAL=BigDecimal.valueOf(LONG.MAX\u VALUE); @凌驾 受保护的字符串sequenceMaxValueColumn(){ 返回“最大值”; } @凌驾 公共长结果集无效(最终结果集结果集)引发SQLException{ final BigDecimal asDecimal=resultSet.getBigDecimal(this.sequenceMinValueColumn()); if(asDecimal.compareTo(SequenceInformationExtractor.LONG\u MIN\u VALUE\u asDecimal)0){ 返回Long.MAX_值; } 返回asDecimal.longValue(); } }
对于PostgreSQL,我使用这个类作为方言,直到Hibernate解决了这个问题:Java SequenceInformation提取器RacledatabaseImpl{ 公共静态最终SequenceInformationExtractor实例=新SequenceInformationExtractor(); 私有静态最终BigDecimal LONG\u MIN\u VALUE\u作为\u DECIMAL=BigDecimal.valueOf(LONG.MIN\u VALUE); 私有静态最终BigDecimal LONG\u MAX\u VALUE\u作为\u DECIMAL=BigDecimal.valueOf(LONG.MAX\u VALUE); @凌驾 受保护的字符串sequenceMaxValueColumn(){ 返回“最大值”; } @凌驾 公共长结果集无效(最终结果集结果集)引发SQLException{ final BigDecimal asDecimal=resultSet.getBigDecimal(this.sequenceMinValueColumn()); if(asDecimal.compareTo(SequenceInformationExtractor.LONG\u MIN\u VALUE\u asDecimal)0){ 返回Long.MAX_值; } 返回asDecimal.longValue(); } },java,spring,oracle,hibernate,Java,Spring,Oracle,Hibernate,对于PostgreSQL,我使用这个类作为方言,直到Hibernate解决了这个问题: package com.societe.dialect; import org.hibernate.dialect.PostgreSQL95Dialect; import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl; import org.hibernate.tool.schema.extra
package com.societe.dialect;
import org.hibernate.dialect.PostgreSQL95Dialect;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
public class PostgresqlCustomDialect extends PostgreSQL95Dialect {
public String getQuerySequencesString() {
return "select * from all_sequences";
}
public SequenceInformationExtractor getSequenceInformationExtractor() {
return SequenceInformationExtractorNoOpImpl.INSTANCE;
}
}
马米特轰炸机,谢谢你的回复。但我担心,在我的情况下,这将不是一个可接受的解决方案,因为我们公司的其他应用程序使用相同的数据库模式,并且由于这种更正可能会受到影响。是的,与其他应用程序共享Hibernate模式会提高risc。您是否至少使用不同的连接用户作为竞争对手?每个应用程序都使用自己的weblogic数据源,但几乎所有这些数据源都使用相同的oracle DB用户。通过此设置,IMO证明您可以很好地管理潜在的risc,因此您应该问1)序列的当前值是多少(
LAST_NUMBER
)2)每年的平均增长是多少,3)何时达到Long.MAX_值的极限。如果未来超过100年,我会将解决方案推迟到那时;)我只是想知道为什么这个异常如此异常,而谷歌搜索“无法从数据库中获取序列信息”“java.sql.SQLException:Numeric Overflow”
这只是现有的第二个匹配项。可能人们会对序列使用真实的非默认值MAX\u值
。谢谢您的回答。其他读者可能希望从所选列中删除“PARTITION_COUNT”,因为它可能不存在于所有Oracle数据库中。请参阅:您不应该也解决最大值设置吗?@W.Elbashier请查看实现。Long-resultSetMaxValue(ResultSet-ResultSet)
方法已被重写。将方言从Oracle更改为MySQL还应假定更改了数据库。我不认为这将是一个重要的应用程序的人可以接受的。看看史蒂夫埃伯索尔的这个拉请求。实际上,Hibernate没有以任何有意义的方式使用方法Long getMinValue()
和Long getMaxValue()
。因此,我的解决方案只允许通过最少的笨拙额外编码来避免异常。
SQL> CREATE SEQUENCE SEQ_TEST START WITH 1 INCREMENT BY 1 NOCYCLE;
SQL> select MIN_VALUE, MAX_VALUE, INCREMENT_BY
from USER_SEQUENCES
where SEQUENCE_NAME = 'SEQ_TEST';
MIN_VALUE MAX_VALUE INCREMENT_BY
--------- ---------------------------- ------------
1 9999999999999999999999999999 1
CREATE SEQUENCE SEQ_TEST START WITH 1 INCREMENT BY 1 NOCYCLE;
select MAX_VALUE from ALL_SEQUENCES where SEQUENCE_NAME = 'SEQ_TEST';
MAX_VALUE
----------
9999999999999999999999999999
ALTER SEQUENCE SEQ_TEST
MAXVALUE 9223372036854775807;
select MAX_VALUE from ALL_SEQUENCES where SEQUENCE_NAME = 'SEQ_TEST';
MAX_VALUE
----------
9223372036854775807
package ru.mvawork.hibernate;
import org.hibernate.dialect.Oracle12cDialect;
@SuppressWarnings("unused")
public class CustomOracleDialect extends Oracle12cDialect {
@Override
public String getQuerySequencesString() {
return "select SEQUENCE_OWNER, SEQUENCE_NAME, greatest(MIN_VALUE, -9223372036854775807) MIN_VALUE,\n"+
"Least(MAX_VALUE, 9223372036854775808) MAX_VALUE, INCREMENT_BY, CYCLE_FLAG, ORDER_FLAG, CACHE_SIZE,\n"+
"Least(greatest(LAST_NUMBER, -9223372036854775807), 9223372036854775808) LAST_NUMBER,\n"+
"PARTITION_COUNT, SESSION_FLAG, KEEP_VALUE\n"+
"from all_sequences";
}
}
spring.jpa.properties.hibernate.dialect=ru.mvawork.hibernate.CustomOracleDialect
@Test
public void testSignChange() {
final BigDecimal minValue = BigDecimal.valueOf(Long.MIN_VALUE);
final BigDecimal minValueMinusTen = minValue.subtract(BigDecimal.TEN);
final long minValueMinusTenLong = minValueMinusTen.longValue();
System.out.println("Min value as big decimal: " + minValueMinusTen);
System.out.println("Min value as long: " + minValueMinusTenLong);
final BigDecimal maxValue = BigDecimal.valueOf(Long.MAX_VALUE);
final BigDecimal maxValuePlusTen = maxValue.add(BigDecimal.TEN);
final long maxValuePlusTenLong = maxValuePlusTen.longValue();
System.out.println("Max value as big decimal: " + maxValuePlusTen);
System.out.println("Max value as long: " + maxValuePlusTenLong);
}
Min value as big decimal: -9223372036854775818
Min value as long: 9223372036854775798
Max value as big decimal: 9223372036854775817
Max value as long: -9223372036854775799
public class SequenceInformationExtractor extends SequenceInformationExtractorOracleDatabaseImpl {
public static final SequenceInformationExtractor INSTANCE = new SequenceInformationExtractor();
private static final BigDecimal LONG_MIN_VALUE_AS_DECIMAL = BigDecimal.valueOf(Long.MIN_VALUE);
private static final BigDecimal LONG_MAX_VALUE_AS_DECIMAL = BigDecimal.valueOf(Long.MAX_VALUE);
@Override
protected String sequenceMaxValueColumn() {
return "max_value";
}
@Override
public Long resultSetMinValue(final ResultSet resultSet) throws SQLException {
final BigDecimal asDecimal = resultSet.getBigDecimal(this.sequenceMinValueColumn());
if (asDecimal.compareTo(SequenceInformationExtractor.LONG_MIN_VALUE_AS_DECIMAL) < 0) {
return Long.MIN_VALUE;
}
return asDecimal.longValue();
}
@Override
public Long resultSetMaxValue(final ResultSet resultSet) throws SQLException {
final BigDecimal asDecimal = resultSet.getBigDecimal(this.sequenceMaxValueColumn());
if (asDecimal.compareTo(SequenceInformationExtractor.LONG_MAX_VALUE_AS_DECIMAL) > 0) {
return Long.MAX_VALUE;
}
return asDecimal.longValue();
}
}
package com.societe.dialect;
import org.hibernate.dialect.PostgreSQL95Dialect;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
public class PostgresqlCustomDialect extends PostgreSQL95Dialect {
public String getQuerySequencesString() {
return "select * from all_sequences";
}
public SequenceInformationExtractor getSequenceInformationExtractor() {
return SequenceInformationExtractorNoOpImpl.INSTANCE;
}
}