I examined the situation with a custom ImplicitNamingStrategy which truncates Hibernate-generated identifiers to 64 characters (maximum length for Postgres).
Previous versions of Hibernate (4.x) encountered the same error, but they simply ignore it and continue to initialize SessionFactory. However, Hibernate 5.x has a new boot strap API that throws a SchemaManagementException in such cases and interrupts operation. Hibernate logs from my test scripts are inserted below for reference.
Hibernate 4.X
INFO: HHH000396: Updating schema Oct 04, 2015 1:38:00 PM org.hibernate.tool.hbm2ddl.DatabaseMetadata getTableMetadata INFO: HHH000262: Table not found: ReferenceDocumentVersionEntityWithAReallyReallyReallyLongNameBeyondPostGres Oct 04, 2015 1:38:00 PM org.hibernate.tool.hbm2ddl.DatabaseMetadata getTableMetadata INFO: HHH000262: Table not found: ReferenceDocumentVersionEntityWithAReallyReallyReallyLongNameBeyondPostGres Oct 04, 2015 1:38:00 PM org.hibernate.tool.hbm2ddl.DatabaseMetadata getTableMetadata INFO: HHH000262: Table not found: ReferenceDocumentVersionEntityWithAReallyReallyReallyLongNameBeyondPostGres Oct 04, 2015 1:38:00 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute ERROR: HHH000388: Unsuccessful: create table ReferenceDocumentVersionEntityWithAReallyReallyReallyLongNameBeyondPostGres (unid uuid not null, path text, primary key (unid)) Oct 04, 2015 1:38:00 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute ERROR: ERROR: relation "referencedocumentversionentitywithareallyreallyreallylongnamebe" already exists Oct 04, 2015 1:38:00 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute INFO: HHH000232: Schema update complete
Hibernate 5.0.2.Final
Oct 04, 2015 1:39:16 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute INFO: HHH000228: Running hbm2ddl schema update Oct 04, 2015 1:39:16 PM org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl processGetTableResults INFO: HHH000262: Table not found: ReferenceDocumentVersionEntityWithAReallyReallyReallyLongNameBeyondPostGres Oct 04, 2015 1:39:16 PM org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl processGetTableResults INFO: HHH000262: Table not found: ReferenceDocumentVersionEntityWithAReallyReallyReallyLongNameBeyondPostGres Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.813 sec <<< FAILURE! testApp(org.foobar.AppTest) Time elapsed: 0.788 sec <<< ERROR! javax.persistence.PersistenceException: [PersistenceUnit: org.foobar.persistence.default] Unable to build Hibernate SessionFactory at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:877) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:805) at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:58) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39) at org.foobar.AppTest.testApp(AppTest.java:18)
Decision
Custom ImplicitNamingStrategy
package org.foobar.persistence; import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl; import org.hibernate.boot.spi.MetadataBuildingContext; public class PGConstrainedImplicitNamingStrategy extends ImplicitNamingStrategyComponentPathImpl { private static final int POSTGRES_IDENTIFIER_MAXLENGTH = 63; public static final PGConstrainedImplicitNamingStrategy INSTANCE = new PGConstrainedImplicitNamingStrategy(); public PGConstrainedImplicitNamingStrategy() { } @Override protected Identifier toIdentifier(String stringForm, MetadataBuildingContext buildingContext) { return buildingContext.getMetadataCollector() .getDatabase() .getJdbcEnvironment() .getIdentifierHelper() .toIdentifier( stringForm.substring( 0, Math.min( POSTGRES_IDENTIFIER_MAXLENGTH, stringForm.length() ) ) ); }}
persistence.xml
<properties> <property name="hibernate.implicit_naming_strategy" value="org.foobar.persistence.PGConstrainedImplicitNamingStrategy"/> </properties>
This is not a scalable solution, but it helps keep the show running. The permanent solution is to explicitly provide identifiers so that hibernate does not generate really long identifiers. - see the answer written by Maaartinus
Shelldragon
source share