Schema Validation fails with a database sequence not returning BIGINT / Long column type in its definition

Description

When enabling the schema validation through hibernate.hbm2ddl.auto=validate, starting from ORM 5.4.0.CR1 up to 5.4.5.Final, due to fix and 1db476dbd5ec4f852472b953d50a8caa073efd6d commit, the validation of a sequence not being of BIGINT type fails.

In class org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl, method extractMetadata() calls resultSetStartValueSize() that in turn calls resultSet.getLong(column).
If the sequence is defined as
CREATE SEQUENCE [dbo].[SampleSequence]
AS [int]
START WITH 1
INCREMENT BY 1
MINVALUE 1
MAXVALUE 100


the underlying jdbc type will be INT, resulting in a java.lang.Integer and causing this exception during schema validation (even if that sequence is not used at all):

javax.persistence.PersistenceException: [PersistenceUnit: PromagWMS] Unable to build Hibernate SessionFactory
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1012) ~[hibernate-core-5.4.5.Final.jar:5.4.5.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:938) ~[hibernate-core-5.4.5.Final.jar:5.4.5.Final]
at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:56) ~[hibernate-core-5.4.5.Final.jar:5.4.5.Final]
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79) ~[javax.persistence-api-2.2.jar:2.2]
... 4 more [...]
Caused by: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.getLong(SQLServerResultSet.java:2328) ~[mssql-jdbc-7.4.1.jre8.jar:?]
at com.zaxxer.hikari.pool.HikariProxyResultSet.getLong(HikariProxyResultSet.java) ~[HikariCP-3.4.1.jar:?]
at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.resultSetStartValueSize(SequenceInformationExtractorLegacyImpl.java:129) ~[hibernate-core-5.4.5.Final.jar:5.4.5.Final]
at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.extractMetadata(SequenceInformationExtractorLegacyImpl.java:59) ~[hibernate-core-5.4.5.Final.jar:5.4.5.Final]
at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.initializeSequences(DatabaseInformationImpl.java:65) ~[hibernate-core-5.4.5.Final.jar:5.4.5.Final]
at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.<init>(DatabaseInformationImpl.java:59) ~[hibernate-core-5.4.5.Final.jar:5.4.5.Final]
at org.hibernate.tool.schema.internal.Helper.buildDatabaseInformation(Helper.java:155) ~[hibernate-core-5.4.5.Final.jar:5.4.5.Final]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.doValidation(AbstractSchemaValidator.java:61) ~[hibernate-core-5.4.5.Final.jar:5.4.5.Final]
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:192) ~[hibernate-core-5.4.5.Final.jar:5.4.5.Final]
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:73) ~[hibernate-core-5.4.5.Final.jar:5.4.5.Final]
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:320) ~[hibernate-core-5.4.5.Final.jar:5.4.5.Final]
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:462) ~[hibernate-core-5.4.5.Final.jar:5.4.5.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:935) ~[hibernate-core-5.4.5.Final.jar:5.4.5.Final]
at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:56) ~[hibernate-core-5.4.5.Final.jar:5.4.5.Final]
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79) ~[javax.persistence-api-2.2.jar:2.2]
... 4 more [...]

My workaround for MSSQL and my specific use-case, is just to change the sequence query string by using a custom dialect that converts columns into BIGINT type:
@Override
public String getQuerySequencesString() {
return "SELECT sequence_name"
+ ", sequence_catalog"
+ ", sequence_schema"
+ ", CONVERT(BIGINT, start_value) start_value"
+ ", CONVERT(BIGINT, minimum_value) minimum_value"
+ ", CONVERT(BIGINT, maximum_value) maximum_value"
+ ", CONVERT(BIGINT, increment) increment"
+ " FROM INFORMATION_SCHEMA.SEQUENCES";
}

Since class SequenceInformationExtractorLegacyImpl just casts those columns to java.lang.Long, I think a similar approach should be taken for every possible dialect, or the explicit cast to Long should be changed to something more robust..

 

Environment

Windows 10
Java 8
Hibernate 5.4.5.Final (down to 5.4.0.CR1)
MSSQL 2016
mssql-jdbc-7.4.1-jre8
HikariCP 3.4.1

Status

Assignee

Unassigned

Reporter

Luca Domenichini

Fix versions

None

Labels

backPortable

Backport?

Suitable for new contributors

Yes, likely

Requires Release Note

None

Pull Request

None

backportDecision

None

Affects versions

Priority

Major
Configure