Hibernate无法从数据库中获取SequenceInformation

我最近将应用程序中的hiberbnate模式更新为5.4.4.Final。现在,在部署过程中我面临以下异常。

ERROR [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl|[STANDBY] ExecuteThread: '5' for queue: 'weblogic.kernel.Default (self-tuning)']

Could not fetch the SequenceInformation from the database

java.sql.SQLException: Numeric Overflow

at oracle.jdbc.driver.NumberCommonAccessor.throwOverflow(NumberCommonAccessor.java:4136)

at oracle.jdbc.driver.NumberCommonAccessor.getLong(NumberCommonAccessor.java:634)

at oracle.jdbc.driver.GeneratedStatement.getLong(GeneratedStatement.java:206)

at oracle.jdbc.driver.GeneratedScrollableResultSet.getLong(GeneratedScrollableResultSet.java:259)

at oracle.jdbc.driver.GeneratedResultSet.getLong(GeneratedResultSet.java:558)

at weblogic.jdbc.wrapper.ResultSet_oracle_jdbc_driver_ForwardOnlyResultSet.getLong(Unknown Source)

at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.resultSetMaxValue(SequenceInformationExtractorLegacyImpl.java:139)

at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.extractMetadata(SequenceInformationExtractorLegacyImpl.java:61)

at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl.sequenceInformationList(JdbcEnvironmentImpl.java:403)

at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl.<init>(JdbcEnvironmentImpl.java:268)

at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:114)

at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)

at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)

at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)

at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)

at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)

at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152)

at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)

at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)

at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)

at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:175)

at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:118)

at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:900)

at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:931)

at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:141)

at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343)

at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)

at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)

at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)

at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)

at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)

at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:956)

at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:747)

at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)

at com.sternkn.app.services.web.AppContextLoaderListener.<clinit>(AppContextLoaderListener.java:30)

我使用以下persistence.xml。

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"

version="2.2">

<persistence-unit name="appPersistenceUnit" transaction-type="RESOURCE_LOCAL">

<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

<properties>

<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle12cDialect" />

<property name="hibernate.id.new_generator_mappings" value="true"/>

<property name="hibernate.cache.use_second_level_cache" value = "true"/>

<property name="hibernate.cache.use_query_cache" value="false" />

<property name="hibernate.cache.region.factory_class" value="ehcache"/>

<property name="hibernate.cache.ehcache.missing_cache_strategy" value="create" />

<property name="hibernate.cache.region_prefix" value="app_cache" />

<property name="net.sf.ehcache.configurationResourceName" value="/META-INF/app-ehcache.xml" />

<property name="hibernate.bytecode.provider" value="bytebuddy" />

</properties>

</persistence-unit>

</persistence>

经过进一步调查,我发现根本原因是:hibernate使用 接口进行序列元数据操作

public interface SequenceInformation {

Long getMinValue();

Long getMaxValue();

Long getIncrementValue();

...

}

但是,我的应用程序使用如下序列:

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

该 等于9223372036854775807,所以我得到的数字溢出异常。

所以,我的问题是:

  • 休眠中的错误吗?
  • 解决问题的最佳方法是什么?

现在,我看到以下方式:

  1. 修复序列声明。就我而言,这可能会很成问题。而且,顺便说一句,休眠试图读取有关所有序列的元数据,而不仅仅是在我的应用程序中使用的元数据,这看起来很奇怪。
  2. 创建将扩展Oracle12cDialect并覆盖getQuerySequencesString()和/或getSequenceInformationExtractor()的自定义方言。

    public class Oracle8iDialect extends Dialect {

...

public String getQuerySequencesString() {

return "select * from all_sequences";

}

public SequenceInformationExtractor getSequenceInformationExtractor() {

return SequenceInformationExtractorOracleDatabaseImpl.INSTANCE;

}

}

我可以将 切换为

并且休眠将不会读取序列元数据。这个决定会有什么影响?Hibernate尝试通过INCREMENT_BY 验证@SequenceGenerator()的

。还有其他原因吗?

任何建议将不胜感激。

:这是HHH-13694

回答:

最后,我提出了以下解决方案:

  1. 创建一个扩展了以下内容的序列信息提取器SequenceInformationExtractorOracleDatabaseImpl

    public class AppSequenceInformationExtractor extends SequenceInformationExtractorOracleDatabaseImpl 

{

/**

* Singleton access

*/

public static final AppSequenceInformationExtractor INSTANCE = new AppSequenceInformationExtractor();

@Override

protected Long resultSetMinValue(ResultSet resultSet) throws SQLException {

return resultSet.getBigDecimal("min_value").longValue();

}

}

  1. 创建一个扩展了的休眠方言Oracle12cDialect

    public class AppOracleDialect extends Oracle12cDialect

{

@Override

public SequenceInformationExtractor getSequenceInformationExtractor() {

return AppSequenceInformationExtractor.INSTANCE;

}

@Override

public String getQuerySequencesString() {

return "select * from user_sequences";

}

}

  1. 然后在persistence.xml:中使用此方言:

至于方法的getQuerySequencesString()替代和用法,USER_SEQUENCES而不是ALL_SEQUENCES值得商(的(请参阅HHH-13322和HHH-14022)。但是,就我而言,USER_SEQUENCES用法更可取。

以上是 Hibernate无法从数据库中获取SequenceInformation 的全部内容, 来源链接: utcz.com/qa/419824.html

回到顶部