From 56ba690366a0152e62f4fb5341fa420fb0786ef6 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Mon, 28 Mar 2022 16:53:49 -0500 Subject: [PATCH] HHH-15143 - Add an "implicit naming strategy" for database structures (sequence and tables) for identifier generators --- .../internal/StrategySelectorBuilder.java | 23 ++ .../org/hibernate/cfg/AvailableSettings.java | 6 +- ...ImplicitDatabaseObjectNamingStrategy.java} | 8 +- ...trategy.java => LegacyNamingStrategy.java} | 30 +- ...ltGeneratorNameDatabaseNamingStrategy.java | 94 ------- ...gacyPreferGeneratorNameNamingStrategy.java | 108 ++++++++ .../id/enhanced/SequenceStyleGenerator.java | 8 +- ...StandardDatabaseObjectNamingStrategy.java} | 43 +-- .../hibernate/id/enhanced/TableGenerator.java | 30 +- .../enhanced/SequenceNamingStrategyTest.java | 201 ++++++++++++++ .../id/enhanced/TableNamingStrategyTest.java | 184 +++++++++++++ ...citDatabaseObjectNamingStrategyTests.java} | 10 +- .../SequenceIdGenerationStrategyTest.java | 258 ------------------ .../TableGenerationStrategyTest.java | 191 ------------- migration-guide.adoc | 4 +- 15 files changed, 592 insertions(+), 606 deletions(-) rename hibernate-core/src/main/java/org/hibernate/{boot/model/naming/spi/ImplicitIdentifierDatabaseObjectNamingStrategy.java => id/enhanced/ImplicitDatabaseObjectNamingStrategy.java} (86%) rename hibernate-core/src/main/java/org/hibernate/id/enhanced/{LegacyNoPreferDefaultGeneratorNameDatabaseNamingStrategy.java => LegacyNamingStrategy.java} (61%) delete mode 100644 hibernate-core/src/main/java/org/hibernate/id/enhanced/LegacyPreferDefaultGeneratorNameDatabaseNamingStrategy.java create mode 100644 hibernate-core/src/main/java/org/hibernate/id/enhanced/LegacyPreferGeneratorNameNamingStrategy.java rename hibernate-core/src/main/java/org/hibernate/id/enhanced/{StandardImplicitIdentifierDatabaseObjectNamingStrategy.java => StandardDatabaseObjectNamingStrategy.java} (79%) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/id/enhanced/SequenceNamingStrategyTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/id/enhanced/TableNamingStrategyTest.java rename hibernate-core/src/test/java/org/hibernate/orm/test/namingstrategy/{ImplicitIdentifierDatabaseObjectNamingStrategyTests.java => ImplicitDatabaseObjectNamingStrategyTests.java} (90%) delete mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/SequenceIdGenerationStrategyTest.java delete mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/TableGenerationStrategyTest.java diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorBuilder.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorBuilder.java index 6f135357bf..954c2509c1 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorBuilder.java @@ -26,6 +26,10 @@ import org.hibernate.cache.internal.SimpleCacheKeysFactory; import org.hibernate.cache.spi.CacheKeysFactory; import org.hibernate.dialect.Dialect; import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform; +import org.hibernate.id.enhanced.ImplicitDatabaseObjectNamingStrategy; +import org.hibernate.id.enhanced.LegacyNamingStrategy; +import org.hibernate.id.enhanced.LegacyPreferGeneratorNameNamingStrategy; +import org.hibernate.id.enhanced.StandardDatabaseObjectNamingStrategy; import org.hibernate.query.sqm.mutation.internal.cte.CteMutationStrategy; import org.hibernate.query.sqm.mutation.internal.temptable.GlobalTemporaryTableMutationStrategy; import org.hibernate.query.sqm.mutation.internal.temptable.LocalTemporaryTableMutationStrategy; @@ -215,6 +219,25 @@ public class StrategySelectorBuilder { "component-path", ImplicitNamingStrategyComponentPathImpl.class ); + + + strategySelector.registerStrategyImplementor( + ImplicitDatabaseObjectNamingStrategy.class, + StandardDatabaseObjectNamingStrategy.STRATEGY_NAME, + StandardDatabaseObjectNamingStrategy.class + ); + + strategySelector.registerStrategyImplementor( + ImplicitDatabaseObjectNamingStrategy.class, + LegacyNamingStrategy.STRATEGY_NAME, + LegacyNamingStrategy.class + ); + + strategySelector.registerStrategyImplementor( + ImplicitDatabaseObjectNamingStrategy.class, + LegacyPreferGeneratorNameNamingStrategy.STRATEGY_NAME, + LegacyPreferGeneratorNameNamingStrategy.class + ); } private void addCacheKeysFactories(StrategySelectorImpl strategySelector) { diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java index 51ca5d3f61..6c1e3c8709 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java @@ -15,7 +15,7 @@ import org.hibernate.CustomEntityDirtinessStrategy; import org.hibernate.Incubating; import org.hibernate.Interceptor; import org.hibernate.SessionFactoryObserver; -import org.hibernate.boot.model.naming.spi.ImplicitIdentifierDatabaseObjectNamingStrategy; +import org.hibernate.id.enhanced.ImplicitDatabaseObjectNamingStrategy; import org.hibernate.cache.spi.TimestampsCacheFactory; import org.hibernate.context.spi.CurrentTenantIdentifierResolver; import org.hibernate.jpa.LegacySpecHints; @@ -780,9 +780,9 @@ public interface AvailableSettings { * An implicit naming-strategy for database structures (tables, sequences) related * to identifier-generators * - * @see ImplicitIdentifierDatabaseObjectNamingStrategy + * @see ImplicitDatabaseObjectNamingStrategy * - * @incubating `ImplicitIdentifierDatabaseObjectNamingStrategy` is considered incubating + * @incubating `ImplicitDatabaseObjectNamingStrategy` is considered incubating */ @Incubating String ID_DB_STRUCTURE_NAMING_STRATEGY = "hibernate.id.db_structure_naming_strategy"; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/naming/spi/ImplicitIdentifierDatabaseObjectNamingStrategy.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/ImplicitDatabaseObjectNamingStrategy.java similarity index 86% rename from hibernate-core/src/main/java/org/hibernate/boot/model/naming/spi/ImplicitIdentifierDatabaseObjectNamingStrategy.java rename to hibernate-core/src/main/java/org/hibernate/id/enhanced/ImplicitDatabaseObjectNamingStrategy.java index 774b3c236a..a1850d81e9 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/naming/spi/ImplicitIdentifierDatabaseObjectNamingStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/id/enhanced/ImplicitDatabaseObjectNamingStrategy.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html */ -package org.hibernate.boot.model.naming.spi; +package org.hibernate.id.enhanced; import java.util.Map; @@ -15,14 +15,12 @@ import org.hibernate.service.ServiceRegistry; /** * A naming strategy specifically for determining the implicit naming of - * tables and sequences relating to identifier-generators. - * - * Used in conjunction with + * tables and sequences relating to enhanced identifier-generators. * * @author Steve Ebersole */ @Incubating -public interface ImplicitIdentifierDatabaseObjectNamingStrategy { +public interface ImplicitDatabaseObjectNamingStrategy { String DEF_SEQUENCE = "hibernate_sequence"; /** diff --git a/hibernate-core/src/main/java/org/hibernate/id/enhanced/LegacyNoPreferDefaultGeneratorNameDatabaseNamingStrategy.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/LegacyNamingStrategy.java similarity index 61% rename from hibernate-core/src/main/java/org/hibernate/id/enhanced/LegacyNoPreferDefaultGeneratorNameDatabaseNamingStrategy.java rename to hibernate-core/src/main/java/org/hibernate/id/enhanced/LegacyNamingStrategy.java index b72a25d74e..6b30bf56ea 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/enhanced/LegacyNoPreferDefaultGeneratorNameDatabaseNamingStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/id/enhanced/LegacyNamingStrategy.java @@ -9,20 +9,21 @@ package org.hibernate.id.enhanced; import java.util.Map; import org.hibernate.boot.model.naming.Identifier; -import org.hibernate.boot.model.naming.spi.ImplicitIdentifierDatabaseObjectNamingStrategy; import org.hibernate.boot.model.relational.QualifiedName; import org.hibernate.boot.model.relational.QualifiedNameParser; import org.hibernate.boot.model.relational.QualifiedSequenceName; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; -import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.service.ServiceRegistry; import static org.hibernate.id.enhanced.TableGenerator.DEF_TABLE; -import static org.hibernate.id.enhanced.TableGenerator.TABLE_PARAM; -public class LegacyNoPreferDefaultGeneratorNameDatabaseNamingStrategy implements - ImplicitIdentifierDatabaseObjectNamingStrategy { +/** + * @author Andrea Boriero + */ +public class LegacyNamingStrategy implements ImplicitDatabaseObjectNamingStrategy { + public static final String STRATEGY_NAME = "legacy"; + @Override public QualifiedName determineSequenceName( Identifier catalogName, Identifier schemaName, @@ -42,18 +43,11 @@ public class LegacyNoPreferDefaultGeneratorNameDatabaseNamingStrategy implements Identifier schemaName, Map configValues, ServiceRegistry serviceRegistry) { - final String tableName = ConfigurationHelper.getString( TABLE_PARAM, configValues, DEF_TABLE ); - - if ( tableName.contains( "." ) ) { - return QualifiedNameParser.INSTANCE.parse( tableName ); - } - else { - final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class ); - return new QualifiedNameParser.NameParts( - catalogName, - schemaName, - jdbcEnvironment.getIdentifierHelper().toIdentifier( tableName ) - ); - } + final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class ); + return new QualifiedNameParser.NameParts( + catalogName, + schemaName, + jdbcEnvironment.getIdentifierHelper().toIdentifier( DEF_TABLE ) + ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/id/enhanced/LegacyPreferDefaultGeneratorNameDatabaseNamingStrategy.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/LegacyPreferDefaultGeneratorNameDatabaseNamingStrategy.java deleted file mode 100644 index 8a1fadb4fb..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/id/enhanced/LegacyPreferDefaultGeneratorNameDatabaseNamingStrategy.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ -package org.hibernate.id.enhanced; - -import java.util.Map; -import java.util.Objects; - -import org.hibernate.boot.model.naming.Identifier; -import org.hibernate.boot.model.naming.spi.ImplicitIdentifierDatabaseObjectNamingStrategy; -import org.hibernate.boot.model.relational.QualifiedName; -import org.hibernate.boot.model.relational.QualifiedNameParser; -import org.hibernate.boot.model.relational.QualifiedSequenceName; -import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; -import org.hibernate.id.IdentifierGenerator; -import org.hibernate.internal.util.StringHelper; -import org.hibernate.internal.util.config.ConfigurationHelper; -import org.hibernate.service.ServiceRegistry; - -import static org.hibernate.id.enhanced.SequenceStyleGenerator.CONFIG_SEQUENCE_PER_ENTITY_SUFFIX; -import static org.hibernate.id.enhanced.SequenceStyleGenerator.DEF_SEQUENCE_SUFFIX; -import static org.hibernate.id.enhanced.TableGenerator.DEF_TABLE; -import static org.hibernate.id.enhanced.TableGenerator.TABLE_PARAM; - -public class LegacyPreferDefaultGeneratorNameDatabaseNamingStrategy implements - ImplicitIdentifierDatabaseObjectNamingStrategy { - - public QualifiedName determineSequenceName( - Identifier catalogName, - Identifier schemaName, - Map configValues, - ServiceRegistry serviceRegistry) { - final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class ); - - return new QualifiedSequenceName( - catalogName, - schemaName, - jdbcEnvironment.getIdentifierHelper().toIdentifier( implicitName( configValues ) ) - ); - } - - private String implicitName(Map configValues) { - final String suffix = ConfigurationHelper.getString( - CONFIG_SEQUENCE_PER_ENTITY_SUFFIX, - configValues, - DEF_SEQUENCE_SUFFIX - ); - - if ( !Objects.equals( suffix, DEF_SEQUENCE_SUFFIX ) ) { - return DEF_SEQUENCE; - } - - final String annotationGeneratorName = ConfigurationHelper.getString( - IdentifierGenerator.GENERATOR_NAME, - configValues - ); - if ( StringHelper.isNotEmpty( annotationGeneratorName ) ) { - return annotationGeneratorName; - } - - return DEF_SEQUENCE; - } - - @Override - public QualifiedName determineTableName( - Identifier catalogName, - Identifier schemaName, - Map configValues, - ServiceRegistry serviceRegistry) { - String fallbackTableName = DEF_TABLE; - - final String generatorName = ConfigurationHelper.getString( IdentifierGenerator.GENERATOR_NAME, configValues ); - if ( StringHelper.isNotEmpty( generatorName ) ) { - fallbackTableName = generatorName; - } - - final String tableName = ConfigurationHelper.getString( TABLE_PARAM, configValues, fallbackTableName ); - - if ( tableName.contains( "." ) ) { - return QualifiedNameParser.INSTANCE.parse( tableName ); - } - else { - final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class ); - return new QualifiedNameParser.NameParts( - catalogName, - schemaName, - jdbcEnvironment.getIdentifierHelper().toIdentifier( tableName ) - ); - } - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/id/enhanced/LegacyPreferGeneratorNameNamingStrategy.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/LegacyPreferGeneratorNameNamingStrategy.java new file mode 100644 index 0000000000..bb41b6ab39 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/id/enhanced/LegacyPreferGeneratorNameNamingStrategy.java @@ -0,0 +1,108 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.id.enhanced; + +import java.util.Map; + +import org.hibernate.boot.model.naming.Identifier; +import org.hibernate.boot.model.relational.QualifiedName; +import org.hibernate.boot.model.relational.QualifiedNameParser; +import org.hibernate.boot.model.relational.QualifiedSequenceName; +import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; +import org.hibernate.id.IdentifierGenerator; +import org.hibernate.id.PersistentIdentifierGenerator; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.internal.util.config.ConfigurationHelper; +import org.hibernate.service.ServiceRegistry; + +import static org.hibernate.id.OptimizableGenerator.IMPLICIT_NAME_BASE; +import static org.hibernate.id.enhanced.SequenceStyleGenerator.CONFIG_SEQUENCE_PER_ENTITY_SUFFIX; +import static org.hibernate.id.enhanced.TableGenerator.DEF_TABLE; + +/** + * Naming strategy which prefers, for sequences
    + *
  1. {@link org.hibernate.id.enhanced.TableGenerator#TABLE_PARAM}
  2. + *
+ * + * + * + * falling back to {@value DEF_SEQUENCE} + */ +public class LegacyPreferGeneratorNameNamingStrategy extends LegacyNamingStrategy { + public static final String STRATEGY_NAME = "prefer-generator-name"; + + public QualifiedName determineSequenceName( + Identifier catalogName, + Identifier schemaName, + Map configValues, + ServiceRegistry serviceRegistry) { + final String sequenceName = implicitSequenceName( configValues ); + + if ( sequenceName.contains( "." ) ) { + return QualifiedNameParser.INSTANCE.parse( sequenceName ); + } + + final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class ); + return new QualifiedSequenceName( + catalogName, + schemaName, + jdbcEnvironment.getIdentifierHelper().toIdentifier( sequenceName ) + ); + } + + private String implicitSequenceName(Map configValues) { + final String explicitSuffix = ConfigurationHelper.getString( CONFIG_SEQUENCE_PER_ENTITY_SUFFIX, configValues ); + final String rootTableName = ConfigurationHelper.getString( PersistentIdentifierGenerator.TABLE, configValues ); + final String base = ConfigurationHelper.getString( IMPLICIT_NAME_BASE, configValues, rootTableName ); + + if ( StringHelper.isNotEmpty( explicitSuffix ) ) { + // an "implicit name suffix" was specified + if ( StringHelper.isNotEmpty( base ) ) { + if ( Identifier.isQuoted( base ) ) { + return "`" + Identifier.unQuote( base ) + explicitSuffix + "`"; + } + return base + explicitSuffix; + } + } + + final String annotationGeneratorName = ConfigurationHelper.getString( IdentifierGenerator.GENERATOR_NAME, configValues ); + if ( StringHelper.isNotEmpty( annotationGeneratorName ) ) { + return annotationGeneratorName; + } + + return DEF_SEQUENCE; + } + + @Override + public QualifiedName determineTableName( + Identifier catalogName, + Identifier schemaName, + Map configValues, + ServiceRegistry serviceRegistry) { + final String implicitName = determineImplicitName( configValues ); + + if ( implicitName.contains( "." ) ) { + return QualifiedNameParser.INSTANCE.parse( implicitName ); + } + + final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class ); + return new QualifiedNameParser.NameParts( + catalogName, + schemaName, + jdbcEnvironment.getIdentifierHelper().toIdentifier( implicitName ) + ); + } + + private String determineImplicitName(Map configValues) { + final String annotationName = ConfigurationHelper.getString( IdentifierGenerator.GENERATOR_NAME, configValues ); + if ( StringHelper.isNotEmpty( annotationName ) ) { + return annotationName; + } + + return DEF_TABLE; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java index e5bc9999a7..ce51265a9d 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java @@ -12,7 +12,6 @@ import java.util.Properties; import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.boot.model.naming.Identifier; -import org.hibernate.boot.model.naming.spi.ImplicitIdentifierDatabaseObjectNamingStrategy; import org.hibernate.boot.model.relational.Database; import org.hibernate.boot.model.relational.QualifiedName; import org.hibernate.boot.model.relational.QualifiedNameParser; @@ -302,7 +301,6 @@ public class SequenceStyleGenerator if ( StringHelper.isNotEmpty( sequenceName ) ) { // we have an explicit name, use it if ( sequenceName.contains( "." ) ) { - // return QualifiedNameParser.INSTANCE.parse( sequenceName ); } else { @@ -341,11 +339,11 @@ public class SequenceStyleGenerator } return globalSetting; }, - StandardImplicitIdentifierDatabaseObjectNamingStrategy.class::getName + StandardDatabaseObjectNamingStrategy.class::getName ); - final ImplicitIdentifierDatabaseObjectNamingStrategy namingStrategy = strategySelector.resolveStrategy( - ImplicitIdentifierDatabaseObjectNamingStrategy.class, + final ImplicitDatabaseObjectNamingStrategy namingStrategy = strategySelector.resolveStrategy( + ImplicitDatabaseObjectNamingStrategy.class, namingStrategySetting ); diff --git a/hibernate-core/src/main/java/org/hibernate/id/enhanced/StandardImplicitIdentifierDatabaseObjectNamingStrategy.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/StandardDatabaseObjectNamingStrategy.java similarity index 79% rename from hibernate-core/src/main/java/org/hibernate/id/enhanced/StandardImplicitIdentifierDatabaseObjectNamingStrategy.java rename to hibernate-core/src/main/java/org/hibernate/id/enhanced/StandardDatabaseObjectNamingStrategy.java index 76983ca464..cea427ded5 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/enhanced/StandardImplicitIdentifierDatabaseObjectNamingStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/id/enhanced/StandardDatabaseObjectNamingStrategy.java @@ -7,11 +7,9 @@ package org.hibernate.id.enhanced; import java.util.Map; -import java.util.Objects; import org.hibernate.MappingException; import org.hibernate.boot.model.naming.Identifier; -import org.hibernate.boot.model.naming.spi.ImplicitIdentifierDatabaseObjectNamingStrategy; import org.hibernate.boot.model.relational.QualifiedName; import org.hibernate.boot.model.relational.QualifiedNameParser; import org.hibernate.boot.model.relational.QualifiedSequenceName; @@ -26,13 +24,12 @@ import static org.hibernate.id.OptimizableGenerator.IMPLICIT_NAME_BASE; import static org.hibernate.id.enhanced.SequenceStyleGenerator.CONFIG_SEQUENCE_PER_ENTITY_SUFFIX; import static org.hibernate.id.enhanced.SequenceStyleGenerator.DEF_SEQUENCE_SUFFIX; import static org.hibernate.id.enhanced.TableGenerator.DEF_TABLE; -import static org.hibernate.id.enhanced.TableGenerator.TABLE_PARAM; /** * @author Steve Ebersole */ -public class StandardImplicitIdentifierDatabaseObjectNamingStrategy implements ImplicitIdentifierDatabaseObjectNamingStrategy { - +public class StandardDatabaseObjectNamingStrategy implements ImplicitDatabaseObjectNamingStrategy { + public static final String STRATEGY_NAME = "default"; @Override public QualifiedName determineSequenceName( @@ -45,6 +42,10 @@ public class StandardImplicitIdentifierDatabaseObjectNamingStrategy implements I final String rootTableName = ConfigurationHelper.getString( PersistentIdentifierGenerator.TABLE, configValues ); final String implicitName = implicitName( rootTableName, configValues, serviceRegistry ); + if ( implicitName.contains( "." ) ) { + return QualifiedNameParser.INSTANCE.parse( implicitName ); + } + return new QualifiedSequenceName( catalogName, schemaName, @@ -56,16 +57,16 @@ public class StandardImplicitIdentifierDatabaseObjectNamingStrategy implements I String rootTableName, Map configValues, ServiceRegistry serviceRegistry) { - final String base = ConfigurationHelper.getString( IMPLICIT_NAME_BASE, configValues ); - final String suffix = ConfigurationHelper.getString( CONFIG_SEQUENCE_PER_ENTITY_SUFFIX, configValues, DEF_SEQUENCE_SUFFIX ); + final String explicitSuffix = ConfigurationHelper.getString( CONFIG_SEQUENCE_PER_ENTITY_SUFFIX, configValues ); + final String base = ConfigurationHelper.getString( IMPLICIT_NAME_BASE, configValues, rootTableName ); - if ( ! Objects.equals( suffix, DEF_SEQUENCE_SUFFIX ) ) { + if ( StringHelper.isNotEmpty( explicitSuffix ) ) { // an "implicit name suffix" was specified if ( StringHelper.isNotEmpty( base ) ) { if ( Identifier.isQuoted( base ) ) { - return "`" + Identifier.unQuote( base ) + suffix + "`"; + return "`" + Identifier.unQuote( base ) + explicitSuffix + "`"; } - return base + suffix; + return base + explicitSuffix; } } @@ -76,9 +77,9 @@ public class StandardImplicitIdentifierDatabaseObjectNamingStrategy implements I if ( StringHelper.isNotEmpty( base ) ) { if ( Identifier.isQuoted( base ) ) { - return "`" + Identifier.unQuote( base ) + suffix + "`"; + return "`" + Identifier.unQuote( base ) + DEF_SEQUENCE_SUFFIX + "`"; } - return base + suffix; + return base + DEF_SEQUENCE_SUFFIX; } throw new MappingException( "Unable to determine implicit sequence name; target table - " + rootTableName ); @@ -90,14 +91,7 @@ public class StandardImplicitIdentifierDatabaseObjectNamingStrategy implements I Identifier schemaName, Map configValues, ServiceRegistry serviceRegistry) { - String fallbackTableName = DEF_TABLE; - - final String generatorName = ConfigurationHelper.getString( IdentifierGenerator.GENERATOR_NAME, configValues ); - if ( StringHelper.isNotEmpty( generatorName ) ) { - fallbackTableName = generatorName; - } - - final String tableName = ConfigurationHelper.getString( TABLE_PARAM, configValues, fallbackTableName ); + final String tableName = implicitTableName( configValues ); if ( tableName.contains( "." ) ) { return QualifiedNameParser.INSTANCE.parse( tableName ); @@ -112,4 +106,13 @@ public class StandardImplicitIdentifierDatabaseObjectNamingStrategy implements I } } + private static String implicitTableName(Map configValues) { + final String generatorName = ConfigurationHelper.getString( IdentifierGenerator.GENERATOR_NAME, configValues ); + if ( StringHelper.isNotEmpty( generatorName ) ) { + return generatorName; + } + + return DEF_TABLE; + } + } diff --git a/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java index 5139007f85..186913fc25 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java @@ -19,11 +19,11 @@ import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.MappingException; import org.hibernate.boot.model.naming.Identifier; -import org.hibernate.boot.model.naming.spi.ImplicitIdentifierDatabaseObjectNamingStrategy; import org.hibernate.boot.model.relational.Database; import org.hibernate.boot.model.relational.InitCommand; import org.hibernate.boot.model.relational.Namespace; import org.hibernate.boot.model.relational.QualifiedName; +import org.hibernate.boot.model.relational.QualifiedNameParser; import org.hibernate.boot.model.relational.SqlStringGenerationContext; import org.hibernate.boot.registry.selector.spi.StrategySelector; import org.hibernate.cfg.AvailableSettings; @@ -373,6 +373,26 @@ public class TableGenerator implements PersistentIdentifierGenerator { * @return The table name to use. */ protected QualifiedName determineGeneratorTableName(Properties params, JdbcEnvironment jdbcEnvironment, ServiceRegistry serviceRegistry) { + final String explicitTableName = ConfigurationHelper.getString( TABLE_PARAM, params ); + if ( StringHelper.isNotEmpty( explicitTableName ) ) { + if ( explicitTableName.contains( "." ) ) { + return QualifiedNameParser.INSTANCE.parse( explicitTableName ); + } + else { + final Identifier catalog = jdbcEnvironment.getIdentifierHelper().toIdentifier( + ConfigurationHelper.getString( CATALOG, params ) + ); + final Identifier schema = jdbcEnvironment.getIdentifierHelper().toIdentifier( + ConfigurationHelper.getString( SCHEMA, params ) + ); + return new QualifiedNameParser.NameParts( + catalog, + schema, + jdbcEnvironment.getIdentifierHelper().toIdentifier( explicitTableName ) + ); + } + } + final StrategySelector strategySelector = serviceRegistry.getService( StrategySelector.class ); final String namingStrategySetting = coalesceSuppliedValues( @@ -391,18 +411,18 @@ public class TableGenerator implements PersistentIdentifierGenerator { } return globalSetting; }, - StandardImplicitIdentifierDatabaseObjectNamingStrategy.class::getName + StandardDatabaseObjectNamingStrategy.class::getName ); - final ImplicitIdentifierDatabaseObjectNamingStrategy namingStrategy = strategySelector.resolveStrategy( - ImplicitIdentifierDatabaseObjectNamingStrategy.class, + final ImplicitDatabaseObjectNamingStrategy namingStrategy = strategySelector.resolveStrategy( + ImplicitDatabaseObjectNamingStrategy.class, namingStrategySetting ); final Identifier catalog = jdbcEnvironment.getIdentifierHelper().toIdentifier( ConfigurationHelper.getString( CATALOG, params ) ); - final Identifier schema = jdbcEnvironment.getIdentifierHelper().toIdentifier( + final Identifier schema = jdbcEnvironment.getIdentifierHelper().toIdentifier( ConfigurationHelper.getString( SCHEMA, params ) ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/id/enhanced/SequenceNamingStrategyTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/id/enhanced/SequenceNamingStrategyTest.java new file mode 100644 index 0000000000..e8eaa54334 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/id/enhanced/SequenceNamingStrategyTest.java @@ -0,0 +1,201 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.orm.test.id.enhanced; + +import java.util.function.Consumer; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.SequenceGenerator; + +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.model.naming.Identifier; +import org.hibernate.boot.model.relational.Namespace; +import org.hibernate.boot.model.relational.Sequence; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.boot.spi.MetadataImplementor; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.id.IdentifierGenerator; +import org.hibernate.id.enhanced.LegacyNamingStrategy; +import org.hibernate.id.enhanced.LegacyPreferGeneratorNameNamingStrategy; +import org.hibernate.id.enhanced.SequenceStructure; +import org.hibernate.id.enhanced.SequenceStyleGenerator; +import org.hibernate.id.enhanced.StandardDatabaseObjectNamingStrategy; +import org.hibernate.mapping.PersistentClass; +import org.hibernate.service.ServiceRegistry; + +import org.hibernate.testing.orm.junit.BaseUnitTest; +import org.hibernate.testing.orm.junit.DialectFeatureChecks; +import org.hibernate.testing.orm.junit.RequiresDialectFeature; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + + +@BaseUnitTest +@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsSequences.class) +public class SequenceNamingStrategyTest { + + @Test + public void testSequenceNameStandardStrategy() { + verify( TestEntity.class, "TestEntity_SEQ" ); + verify( TestEntity.class, StandardDatabaseObjectNamingStrategy.STRATEGY_NAME, "TestEntity_SEQ" ); + verify( TestEntity.class, StandardDatabaseObjectNamingStrategy.class.getName(), "TestEntity_SEQ" ); + } + + @Test + public void testSequenceNameHibernateSequenceStrategy() { + verify( TestEntity.class, LegacyNamingStrategy.STRATEGY_NAME, "hibernate_sequence" ); + verify( TestEntity.class, LegacyNamingStrategy.class.getName(), "hibernate_sequence" ); + } + + @Test + public void testSequenceNamePreferGeneratorNameStrategy() { + verify( TestEntity.class, LegacyPreferGeneratorNameNamingStrategy.STRATEGY_NAME, "hibernate_sequence" ); + verify( TestEntity.class, LegacyPreferGeneratorNameNamingStrategy.class.getName(), "hibernate_sequence" ); + } + + @Test + public void testNoGeneratorStandardStrategy() { + verify( TestEntity2.class, "table_generator" ); + verify( TestEntity2.class, StandardDatabaseObjectNamingStrategy.STRATEGY_NAME, "table_generator" ); + verify( TestEntity2.class, StandardDatabaseObjectNamingStrategy.class.getName(), "table_generator" ); + } + + @Test + public void testNoGeneratorHibernateSequenceStrategy() { + verify( TestEntity2.class, LegacyNamingStrategy.STRATEGY_NAME, "hibernate_sequence" ); + verify( TestEntity2.class, LegacyNamingStrategy.class.getName(), "hibernate_sequence" ); + } + + @Test + public void testNoGeneratorPreferGeneratorNameStrategy() { + verify( TestEntity2.class, LegacyPreferGeneratorNameNamingStrategy.STRATEGY_NAME, "table_generator" ); + verify( TestEntity2.class, LegacyPreferGeneratorNameNamingStrategy.class.getName(), "table_generator" ); + } + + @Test + public void testGeneratorWithoutSequenceNameStandardStrategy() { + verify( TestEntity3.class, "table_generator" ); + verify( TestEntity3.class, StandardDatabaseObjectNamingStrategy.STRATEGY_NAME, "table_generator" ); + verify( TestEntity3.class, StandardDatabaseObjectNamingStrategy.class.getName(), "table_generator" ); + } + + @Test + public void testGeneratorWithoutSequenceNameHibernateSequenceStrategy() { + verify( TestEntity3.class, LegacyNamingStrategy.STRATEGY_NAME, "hibernate_sequence" ); + verify( TestEntity3.class, LegacyNamingStrategy.class.getName(), "hibernate_sequence" ); + } + + @Test + public void testGeneratorWithoutSequenceNamePreferGeneratorNameStrategy() { + verify( TestEntity3.class, LegacyPreferGeneratorNameNamingStrategy.STRATEGY_NAME, "table_generator" ); + verify( TestEntity3.class, LegacyPreferGeneratorNameNamingStrategy.class.getName(), "table_generator" ); + } + + @Test + public void testGeneratorWithSequenceNameStandardStrategy() throws Exception { + verify( TestEntity4.class, "test_sequence" ); + verify( TestEntity4.class, StandardDatabaseObjectNamingStrategy.STRATEGY_NAME, "test_sequence" ); + verify( TestEntity4.class, StandardDatabaseObjectNamingStrategy.class.getName(), "test_sequence" ); + } + + @Test + public void testGeneratorWithSequenceNameHibernateSequenceStrategy() { + verify( TestEntity4.class, LegacyNamingStrategy.STRATEGY_NAME, "test_sequence" ); + verify( TestEntity4.class, LegacyNamingStrategy.class.getName(), "test_sequence" ); + } + + @Test + public void testGeneratorWithSequenceNamePreferGeneratorNameStrategy() throws Exception { + verify( TestEntity4.class, LegacyPreferGeneratorNameNamingStrategy.STRATEGY_NAME, "test_sequence" ); + verify( TestEntity4.class, LegacyPreferGeneratorNameNamingStrategy.class.getName(), "test_sequence" ); + } + + private void verify(Class entityType, String expectedName) { + verify( entityType, null, expectedName ); + } + + private void verify(Class entityType, String strategy, String expectedName) { + withMetadata( entityType, strategy, (metadata) -> { + final Namespace defaultNamespace = metadata.getDatabase().getDefaultNamespace(); + final Sequence sequence = defaultNamespace.locateSequence( Identifier.toIdentifier( expectedName ) ); + assertThat( sequence ).isNotNull(); + + final PersistentClass entityBinding = metadata.getEntityBinding( entityType.getName() ); + final IdentifierGenerator generator = extractGenerator( entityBinding ); + assertThat( generator ).isInstanceOf( SequenceStyleGenerator.class ); + final SequenceStyleGenerator sequenceStyleGenerator = (SequenceStyleGenerator) generator; + assertThat( sequenceStyleGenerator.getDatabaseStructure() ).isInstanceOf( SequenceStructure.class ); + final SequenceStructure sequenceStructure = (SequenceStructure) sequenceStyleGenerator.getDatabaseStructure(); + assertThat( sequenceStructure.getPhysicalName().getObjectName().getText() ).isEqualTo( expectedName ); + } ); + } + + private static void withMetadata(Class entityClass, String namingStrategy, Consumer consumer) { + final StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder(); + ssrb.applySetting( AvailableSettings.FORMAT_SQL, "false" ); + + if ( namingStrategy != null ) { + ssrb.applySetting( AvailableSettings.ID_DB_STRUCTURE_NAMING_STRATEGY, namingStrategy ); + } + + try ( final ServiceRegistry ssr = ssrb.build() ) { + final MetadataSources metadataSources = new MetadataSources( ssr ); + metadataSources.addAnnotatedClass( entityClass ); + + final MetadataImplementor metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.validate(); + + consumer.accept( metadata ); + } + } + + private IdentifierGenerator extractGenerator(PersistentClass entityBinding) { + return entityBinding.getIdentifier().createIdentifierGenerator( null, null, null ); + } + + @Entity(name = "TestEntity") + public static class TestEntity { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + private Long id; + + private String name; + } + + @Entity(name = "TestEntity2") + public static class TestEntity2 { + @Id + @GeneratedValue(generator = "table_generator") + private Long id; + + private String name; + } + + @Entity(name = "TestEntity3") + public static class TestEntity3 { + @Id + @GeneratedValue(generator = "table_generator") + @SequenceGenerator(name = "table_generator") + private Long id; + + private String name; + } + + @Entity(name = "TestEntity4") + public static class TestEntity4 { + @Id + @GeneratedValue(generator = "table_generator") + @SequenceGenerator(name = "table_generator", sequenceName = "test_sequence") + private Long id; + + private String name; + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/id/enhanced/TableNamingStrategyTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/id/enhanced/TableNamingStrategyTest.java new file mode 100644 index 0000000000..c9c4d179a0 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/id/enhanced/TableNamingStrategyTest.java @@ -0,0 +1,184 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.orm.test.id.enhanced; + +import java.util.function.Consumer; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.TableGenerator; + +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.model.naming.Identifier; +import org.hibernate.boot.model.relational.Namespace; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.boot.spi.MetadataImplementor; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.id.IdentifierGenerator; +import org.hibernate.id.enhanced.LegacyNamingStrategy; +import org.hibernate.id.enhanced.LegacyPreferGeneratorNameNamingStrategy; +import org.hibernate.id.enhanced.StandardDatabaseObjectNamingStrategy; +import org.hibernate.mapping.PersistentClass; +import org.hibernate.mapping.Table; +import org.hibernate.service.ServiceRegistry; + +import org.hibernate.testing.orm.junit.BaseUnitTest; +import org.junit.jupiter.api.Test; + +import static jakarta.persistence.GenerationType.TABLE; +import static org.assertj.core.api.Assertions.assertThat; + +@BaseUnitTest +public class TableNamingStrategyTest { + @Test + public void testTableNameStandardStrategy() { + verifyStandardStrategy( TestEntity.class, "hibernate_sequences" ); + } + + @Test + public void testNoGeneratorStandardStrategy() { + verifyStandardStrategy( TestEntity2.class, "table_generator" ); + } + + @Test + public void testNoGeneratorNoPreferGeneratorNameStrategy() { + verifyLegacyStrategy( TestEntity2.class, "hibernate_sequences" ); + } + + @Test + public void testNoGeneratorPreferGeneratorNameStrategy() { + verifyLegacyPreferStrategy( TestEntity2.class, "table_generator" ); + } + + @Test + public void testGeneratorWithoutSequenceNameStandardStrategy() { + verifyStandardStrategy( TestEntity3.class, "table_generator" ); + } + + @Test + public void testGeneratorWithoutSequenceNameStandardStrategyNoPreferGeneratorNameStrategy() { + verifyLegacyStrategy( TestEntity3.class, "hibernate_sequences" ); + } + + @Test + public void testGeneratorWithoutSequenceNameStandardStrategyPreferGeneratorNameStrategy() { + verifyLegacyPreferStrategy( TestEntity3.class, "table_generator" ); + } + + @Test + public void testGeneratorWithSequenceNameStandardStrategy() { + verifyStandardStrategy( TestEntity4.class, "test_table" ); + } + + @Test + public void testGeneratorWithSequenceNameNoPreferGeneratorNameStrategy() { + verifyLegacyStrategy( TestEntity4.class, "test_table" ); + } + + @Test + public void testGeneratorWithSequenceNamePreferGeneratorNameStrategy() { + verifyLegacyPreferStrategy( TestEntity4.class, "test_table" ); + } + + private void verifyStandardStrategy(Class entityClass, String expectedName) { + verify( entityClass, expectedName ); + verify( entityClass, StandardDatabaseObjectNamingStrategy.STRATEGY_NAME, expectedName ); + verify( entityClass, StandardDatabaseObjectNamingStrategy.class.getName(), expectedName ); + } + + private void verifyLegacyStrategy(Class entityClass, String expectedName) { + verify( entityClass, LegacyNamingStrategy.STRATEGY_NAME, expectedName ); + verify( entityClass, LegacyNamingStrategy.class.getName(), expectedName ); + } + + private void verifyLegacyPreferStrategy(Class entityClass, String expectedName) { + verify( entityClass, LegacyPreferGeneratorNameNamingStrategy.STRATEGY_NAME, expectedName ); + verify( entityClass, LegacyPreferGeneratorNameNamingStrategy.class.getName(), expectedName ); + } + + private void verify(Class entityType, String expectedName) { + verify( entityType, null, expectedName ); + } + + private void verify(Class entityType, String strategy, String expectedName) { + withMetadata( entityType, strategy, (metadata) -> { + final Namespace defaultNamespace = metadata.getDatabase().getDefaultNamespace(); + final Table table = defaultNamespace.locateTable( Identifier.toIdentifier( expectedName ) ); + assertThat( table ).isNotNull(); + + final PersistentClass entityBinding = metadata.getEntityBinding( entityType.getName() ); + final IdentifierGenerator generator = extractGenerator( entityBinding ); + assertThat( generator ).isInstanceOf( org.hibernate.id.enhanced.TableGenerator.class ); + final org.hibernate.id.enhanced.TableGenerator tableGenerator = (org.hibernate.id.enhanced.TableGenerator) generator; + assertThat( tableGenerator.getTableName() ).isEqualTo( expectedName ); + } ); + } + + private static void withMetadata(Class entityClass, String namingStrategy, Consumer consumer) { + final StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder(); + ssrb.applySetting( AvailableSettings.FORMAT_SQL, "false" ); + + if ( namingStrategy != null ) { + ssrb.applySetting( AvailableSettings.ID_DB_STRUCTURE_NAMING_STRATEGY, namingStrategy ); + } + + try ( final ServiceRegistry ssr = ssrb.build() ) { + final MetadataSources metadataSources = new MetadataSources( ssr ); + metadataSources.addAnnotatedClass( entityClass ); + + final MetadataImplementor metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.validate(); + + consumer.accept( metadata ); + } + } + + private IdentifierGenerator extractGenerator(PersistentClass entityBinding) { + return entityBinding.getIdentifier().createIdentifierGenerator( null, null, null ); + } + + + @Entity(name = "TestEntity") + public static class TestEntity { + @Id + @GeneratedValue(strategy = TABLE) + private Long id; + + private String name; + } + + @Entity(name = "TestEntity2") + public static class TestEntity2 { + @Id + @GeneratedValue(strategy = TABLE, generator = "table_generator") + private Long id; + + private String name; + } + + @Entity(name = "TestEntity3") + public static class TestEntity3 { + @Id + @GeneratedValue(generator = "table_generator") + @TableGenerator(name = "table_generator") + private Long id; + + private String name; + } + + @Entity(name = "TestEntity4") + public static class TestEntity4 { + @Id + @GeneratedValue(generator = "table_generator") + @TableGenerator(name = "table_generator", table = "test_table") + private Long id; + + private String name; + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/namingstrategy/ImplicitIdentifierDatabaseObjectNamingStrategyTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/namingstrategy/ImplicitDatabaseObjectNamingStrategyTests.java similarity index 90% rename from hibernate-core/src/test/java/org/hibernate/orm/test/namingstrategy/ImplicitIdentifierDatabaseObjectNamingStrategyTests.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/namingstrategy/ImplicitDatabaseObjectNamingStrategyTests.java index 57aa5cda68..88cd7d6889 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/namingstrategy/ImplicitIdentifierDatabaseObjectNamingStrategyTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/namingstrategy/ImplicitDatabaseObjectNamingStrategyTests.java @@ -15,7 +15,7 @@ import jakarta.persistence.Id; import jakarta.persistence.Table; import org.hibernate.boot.model.naming.Identifier; -import org.hibernate.boot.model.naming.spi.ImplicitIdentifierDatabaseObjectNamingStrategy; +import org.hibernate.id.enhanced.ImplicitDatabaseObjectNamingStrategy; import org.hibernate.boot.model.relational.QualifiedName; import org.hibernate.boot.model.relational.QualifiedSequenceName; import org.hibernate.cfg.AvailableSettings; @@ -41,11 +41,11 @@ import static org.assertj.core.api.Assertions.assertThat; @org.hibernate.testing.orm.junit.ServiceRegistry( settings = @Setting( name = AvailableSettings.ID_DB_STRUCTURE_NAMING_STRATEGY, - value = "org.hibernate.orm.test.namingstrategy.ImplicitIdentifierDatabaseObjectNamingStrategyTests$Strategy" + value = "org.hibernate.orm.test.namingstrategy.ImplicitDatabaseObjectNamingStrategyTests$Strategy" ) ) -@DomainModel( annotatedClasses = ImplicitIdentifierDatabaseObjectNamingStrategyTests.TheEntity.class ) -public class ImplicitIdentifierDatabaseObjectNamingStrategyTests { +@DomainModel( annotatedClasses = ImplicitDatabaseObjectNamingStrategyTests.TheEntity.class ) +public class ImplicitDatabaseObjectNamingStrategyTests { @Test public void testIt(DomainModelScope domainModelScope, ServiceRegistryScope serviceRegistryScope) { @@ -68,7 +68,7 @@ public class ImplicitIdentifierDatabaseObjectNamingStrategyTests { } ); } - public static class Strategy implements ImplicitIdentifierDatabaseObjectNamingStrategy { + public static class Strategy implements ImplicitDatabaseObjectNamingStrategy { @Override public QualifiedName determineSequenceName( Identifier catalogName, diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/SequenceIdGenerationStrategyTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/SequenceIdGenerationStrategyTest.java deleted file mode 100644 index 986793ff5f..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/SequenceIdGenerationStrategyTest.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ -package org.hibernate.orm.test.schemaupdate.idgenerator; - -import java.io.File; -import java.nio.file.Files; -import java.util.EnumSet; - -import org.hibernate.boot.MetadataSources; -import org.hibernate.boot.registry.StandardServiceRegistryBuilder; -import org.hibernate.boot.spi.MetadataImplementor; -import org.hibernate.cfg.AvailableSettings; -import org.hibernate.id.enhanced.LegacyNoPreferDefaultGeneratorNameDatabaseNamingStrategy; -import org.hibernate.id.enhanced.LegacyPreferDefaultGeneratorNameDatabaseNamingStrategy; -import org.hibernate.service.ServiceRegistry; -import org.hibernate.tool.hbm2ddl.SchemaExport; -import org.hibernate.tool.schema.TargetType; - -import org.hibernate.testing.ServiceRegistryBuilder; -import org.hibernate.testing.orm.junit.BaseUnitTest; -import org.hibernate.testing.orm.junit.DialectFeatureChecks; -import org.hibernate.testing.orm.junit.RequiresDialectFeature; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.SequenceGenerator; - -import static org.junit.jupiter.api.Assertions.assertTrue; - - -@BaseUnitTest -@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsSequences.class) -public class SequenceIdGenerationStrategyTest { - - private File output; - private ServiceRegistry ssr; - private MetadataImplementor metadata; - - @BeforeEach - public void setUp() throws Exception { - output = File.createTempFile( "update_script", ".sql" ); - output.deleteOnExit(); - } - - private void buildMetadata(Class annotatedClass) { - buildMetadata( null, annotatedClass ); - } - - private void buildMetadata(String namingStrategy, Class annotatedClass) { - StandardServiceRegistryBuilder standardServiceRegistryBuilder = new StandardServiceRegistryBuilder(); - standardServiceRegistryBuilder.applySetting( AvailableSettings.FORMAT_SQL, "false" ); - - if ( namingStrategy != null ) { - standardServiceRegistryBuilder.applySetting( - AvailableSettings.ID_DB_STRUCTURE_NAMING_STRATEGY, - namingStrategy - ); - } - - ssr = standardServiceRegistryBuilder.build(); - final MetadataSources metadataSources = new MetadataSources( ssr ); - metadataSources.addAnnotatedClass( annotatedClass ); - metadata = (MetadataImplementor) metadataSources.buildMetadata(); - metadata.validate(); - } - - @AfterEach - public void tearDown() { - new SchemaExport().drop( EnumSet.of( TargetType.DATABASE ), metadata ); - ServiceRegistryBuilder.destroy( ssr ); - } - - @Test - public void testSequenceNameStandardStrategy() throws Exception { - buildMetadata( TestEntity.class ); - - createSchema(); - - final String fileContent = new String( Files.readAllBytes( output.toPath() ) ); - assertTrue( fileContent.contains( "TestEntity_SEQ" ) ); - } - - @Test - public void testSequenceNameHibernateSequenceStrategy() throws Exception { - buildMetadata( LegacyNoPreferDefaultGeneratorNameDatabaseNamingStrategy.class.getName(), TestEntity.class ); - - createSchema(); - - final String fileContent = new String( Files.readAllBytes( output.toPath() ) ); - assertTrue( fileContent.contains( "hibernate_sequence" ) ); - } - - @Test - public void testSequenceNamePreferGeneratorNameStrategy() throws Exception { - buildMetadata( - LegacyPreferDefaultGeneratorNameDatabaseNamingStrategy.class.getName(), - TestEntity.class - ); - - createSchema(); - - final String fileContent = new String( Files.readAllBytes( output.toPath() ) ); - assertTrue( fileContent.contains( "hibernate_sequence" ) ); - } - - @Test - public void testNoGeneratorStandardStrategy() throws Exception { - buildMetadata( TestEntity2.class ); - - createSchema(); - - final String fileContent = new String( Files.readAllBytes( output.toPath() ) ); - assertTrue( fileContent.contains( "table_generator" ) ); - } - - @Test - public void testNoGeneratorHibernateSequenceStrategy() throws Exception { - buildMetadata( LegacyNoPreferDefaultGeneratorNameDatabaseNamingStrategy.class.getName(), TestEntity2.class ); - - createSchema(); - - final String fileContent = new String( Files.readAllBytes( output.toPath() ) ); - assertTrue( fileContent.contains( "hibernate_sequence" ) ); - } - - @Test - public void testNoGeneratorPreferGeneratorNameStrategy() throws Exception { - buildMetadata( - LegacyPreferDefaultGeneratorNameDatabaseNamingStrategy.class.getName(), - TestEntity2.class - ); - - createSchema(); - - final String fileContent = new String( Files.readAllBytes( output.toPath() ) ); - assertTrue( fileContent.contains( "table_generator" ) ); - } - - @Test - public void testGeneratorWithoutSequenceNameStandardStrategy() throws Exception { - buildMetadata( TestEntity3.class ); - - createSchema(); - - final String fileContent = new String( Files.readAllBytes( output.toPath() ) ); - assertTrue( fileContent.contains( "table_generator" ) ); - } - - @Test - public void testGeneratorWithoutSequenceNameHibernateSequenceStrategy() throws Exception { - buildMetadata( LegacyNoPreferDefaultGeneratorNameDatabaseNamingStrategy.class.getName(), TestEntity3.class ); - - createSchema(); - - final String fileContent = new String( Files.readAllBytes( output.toPath() ) ); - assertTrue( fileContent.contains( "hibernate_sequence" ) ); - } - - @Test - public void testGeneratorWithoutSequenceNamePreferGeneratorNameStrategy() throws Exception { - buildMetadata( - LegacyPreferDefaultGeneratorNameDatabaseNamingStrategy.class.getName(), - TestEntity3.class - ); - - createSchema(); - - final String fileContent = new String( Files.readAllBytes( output.toPath() ) ); - assertTrue( fileContent.contains( "table_generator" ) ); - } - - @Test - public void testGeneratorWithSequenceNameStandardStrategy() throws Exception { - buildMetadata( TestEntity4.class ); - - createSchema(); - - final String fileContent = new String( Files.readAllBytes( output.toPath() ) ); - assertTrue( fileContent.contains( "test_sequence" ) ); - } - - @Test - public void testGeneratorWithSequenceNameHibernateSequenceStrategy() throws Exception { - buildMetadata( LegacyNoPreferDefaultGeneratorNameDatabaseNamingStrategy.class.getName(), TestEntity4.class ); - - createSchema(); - - final String fileContent = new String( Files.readAllBytes( output.toPath() ) ); - assertTrue( fileContent.contains( "test_sequence" ) ); - } - - @Test - public void testGeneratorWithSequenceNamePreferGeneratorNameStrategy() throws Exception { - buildMetadata( - LegacyPreferDefaultGeneratorNameDatabaseNamingStrategy.class.getName(), - TestEntity4.class - ); - - createSchema(); - - final String fileContent = new String( Files.readAllBytes( output.toPath() ) ); - assertTrue( fileContent.contains( "test_sequence" ) ); - } - - private void createSchema() { - final SchemaExport schemaExport = new SchemaExport(); - schemaExport.setOutputFile( output.getAbsolutePath() ); - schemaExport.create( EnumSet.of( TargetType.DATABASE, TargetType.SCRIPT ), metadata ); - } - - @Entity(name = "TestEntity") - public static class TestEntity { - @Id - @GeneratedValue(strategy = GenerationType.SEQUENCE) - private Long id; - - private String name; - } - - @Entity(name = "TestEntity2") - public static class TestEntity2 { - @Id - @GeneratedValue(generator = "table_generator") - private Long id; - - private String name; - } - - @Entity(name = "TestEntity3") - public static class TestEntity3 { - @Id - @GeneratedValue(generator = "table_generator") - @SequenceGenerator(name = "table_generator") - private Long id; - - private String name; - } - - @Entity(name = "TestEntity4") - public static class TestEntity4 { - @Id - @GeneratedValue(generator = "table_generator") - @SequenceGenerator(name = "table_generator", sequenceName = "test_sequence") - private Long id; - - private String name; - } - -} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/TableGenerationStrategyTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/TableGenerationStrategyTest.java deleted file mode 100644 index 4393012b25..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/TableGenerationStrategyTest.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ -package org.hibernate.orm.test.schemaupdate.idgenerator; - -import java.io.File; -import java.nio.file.Files; -import java.util.EnumSet; - -import org.hibernate.boot.MetadataSources; -import org.hibernate.boot.registry.StandardServiceRegistryBuilder; -import org.hibernate.boot.spi.MetadataImplementor; -import org.hibernate.cfg.AvailableSettings; -import org.hibernate.id.enhanced.LegacyNoPreferDefaultGeneratorNameDatabaseNamingStrategy; -import org.hibernate.service.ServiceRegistry; -import org.hibernate.tool.hbm2ddl.SchemaExport; -import org.hibernate.tool.schema.TargetType; - -import org.hibernate.testing.ServiceRegistryBuilder; -import org.hibernate.testing.orm.junit.BaseUnitTest; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.TableGenerator; - -import static org.junit.jupiter.api.Assertions.assertTrue; - -@BaseUnitTest -public class TableGenerationStrategyTest { - private File output; - private ServiceRegistry ssr; - private MetadataImplementor metadata; - - @BeforeEach - public void setUp() throws Exception { - output = File.createTempFile( "update_script", ".sql" ); - output.deleteOnExit(); - } - - @AfterEach - public void tearDown() { - new SchemaExport().drop( EnumSet.of( TargetType.DATABASE ), metadata ); - ServiceRegistryBuilder.destroy( ssr ); - } - - private void buildMetadata(Class annotatedClass) { - buildMetadata( null, annotatedClass ); - } - - private void buildMetadata(String namingStrategy, Class annotatedClass) { - StandardServiceRegistryBuilder standardServiceRegistryBuilder = new StandardServiceRegistryBuilder(); - standardServiceRegistryBuilder.applySetting( AvailableSettings.FORMAT_SQL, "false" ); - - if ( namingStrategy != null ) { - standardServiceRegistryBuilder.applySetting( - AvailableSettings.ID_DB_STRUCTURE_NAMING_STRATEGY, - namingStrategy - ); - } - - ssr = standardServiceRegistryBuilder.build(); - final MetadataSources metadataSources = new MetadataSources( ssr ); - metadataSources.addAnnotatedClass( annotatedClass ); - metadata = (MetadataImplementor) metadataSources.buildMetadata(); - metadata.validate(); - } - - private void createSchema() { - final SchemaExport schemaExport = new SchemaExport(); - schemaExport.setOutputFile( output.getAbsolutePath() ); - schemaExport.create( EnumSet.of( TargetType.DATABASE, TargetType.SCRIPT ), metadata ); - } - - @Test - public void testTableNameStandardStrategy() throws Exception { - buildMetadata( TestEntity.class ); - - createSchema(); - - final String fileContent = new String( Files.readAllBytes( output.toPath() ) ); - assertTrue( fileContent.contains( "hibernate_sequences" ) ); - } - - @Test - public void testNoGeneratorStandardStrategy() throws Exception { - buildMetadata( TestEntity2.class ); - - createSchema(); - - final String fileContent = new String( Files.readAllBytes( output.toPath() ) ); - assertTrue( fileContent.contains( "table_generator" ) ); - } - - @Test - public void testNoGeneratorNoPreferGeneratorNameStrategy() throws Exception { - buildMetadata( LegacyNoPreferDefaultGeneratorNameDatabaseNamingStrategy.class.getName(), TestEntity2.class ); - - createSchema(); - - final String fileContent = new String( Files.readAllBytes( output.toPath() ) ); - assertTrue( fileContent.contains( "hibernate_sequence" ) ); - } - - @Test - public void testGeneratorWithoutSequenceNameStandardStrategy() throws Exception { - buildMetadata( TestEntity3.class ); - - createSchema(); - - final String fileContent = new String( Files.readAllBytes( output.toPath() ) ); - assertTrue( fileContent.contains( "table_generator" ) ); - } - - @Test - public void testGeneratorWithoutSequenceNameStandardStrategyNoPreferGeneratorNameStrategy() throws Exception { - buildMetadata( LegacyNoPreferDefaultGeneratorNameDatabaseNamingStrategy.class.getName(), TestEntity3.class ); - - createSchema(); - - final String fileContent = new String( Files.readAllBytes( output.toPath() ) ); - assertTrue( fileContent.contains( "hibernate_sequences" ) ); - } - - @Test - public void testGeneratorWithSequenceNameStandardStrategy() throws Exception { - buildMetadata( TestEntity4.class ); - - createSchema(); - - final String fileContent = new String( Files.readAllBytes( output.toPath() ) ); - assertTrue( fileContent.contains( "test_table" ) ); - } - - @Test - public void testGeneratorWithSequenceNameNoPreferGeneratorNameStrategy() throws Exception { - buildMetadata( LegacyNoPreferDefaultGeneratorNameDatabaseNamingStrategy.class.getName(), TestEntity4.class ); - - createSchema(); - - final String fileContent = new String( Files.readAllBytes( output.toPath() ) ); - assertTrue( fileContent.contains( "test_table" ) ); - } - - - @Entity(name = "TestEntity") - public static class TestEntity { - @Id - @GeneratedValue(strategy = GenerationType.TABLE) - private Long id; - - private String name; - } - - @Entity(name = "TestEntity2") - public static class TestEntity2 { - @Id - @GeneratedValue(generator = "table_generator") - private Long id; - - private String name; - } - - @Entity(name = "TestEntity3") - public static class TestEntity3 { - @Id - @GeneratedValue(generator = "table_generator") - @TableGenerator(name = "table_generator") - private Long id; - - private String name; - } - - @Entity(name = "TestEntity4") - public static class TestEntity4 { - @Id - @GeneratedValue(generator = "table_generator") - @TableGenerator(name = "table_generator", table = "test_table") - private Long id; - - private String name; - } - -} diff --git a/migration-guide.adoc b/migration-guide.adoc index c203d824b0..e846c8e4ff 100644 --- a/migration-guide.adoc +++ b/migration-guide.adoc @@ -109,11 +109,11 @@ In order to maintain backward compatibility a new setting `hibernate.id.db_struc In case the code has a generator name with no matching generator or with a generator not specifying a sequence or table name and the property `hibernate.model.generator_name_as_sequence_name` is not set to `false` then to maintain the backward compatibility is necessary to set -hibernate.id.db_structure_naming_strategy=org.hibernate.id.enhanced.LegacyPreferDefaultGeneratorNameDatabaseNamingStrategy +hibernate.id.db_structure_naming_strategy=org.hibernate.id.enhanced.LegacyPreferGeneratorNameNamingStrategy ``` otherwise ``` -hibernate.id.db_structure_naming_strategy=org.hibernate.id.enhanced.LegacyNoPreferDefaultGeneratorNameDatabaseNamingStrategy +hibernate.id.db_structure_naming_strategy=org.hibernate.id.enhanced.LegacyNamingStrategy ``` [[type]]