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 [ HHH-12973 ] 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... |
|