HHH-15143 - Add an "implicit naming strategy" for database structures (sequence and tables) for identifier generators
- clean up, javadoc, migration-guide
This commit is contained in:
parent
56ba690366
commit
e433f32fc6
|
@ -27,9 +27,9 @@ 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.SingleNamingStrategy;
|
||||
import org.hibernate.id.enhanced.LegacyNamingStrategy;
|
||||
import org.hibernate.id.enhanced.LegacyPreferGeneratorNameNamingStrategy;
|
||||
import org.hibernate.id.enhanced.StandardDatabaseObjectNamingStrategy;
|
||||
import org.hibernate.id.enhanced.StandardNamingStrategy;
|
||||
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;
|
||||
|
@ -223,8 +223,14 @@ public class StrategySelectorBuilder {
|
|||
|
||||
strategySelector.registerStrategyImplementor(
|
||||
ImplicitDatabaseObjectNamingStrategy.class,
|
||||
StandardDatabaseObjectNamingStrategy.STRATEGY_NAME,
|
||||
StandardDatabaseObjectNamingStrategy.class
|
||||
StandardNamingStrategy.STRATEGY_NAME,
|
||||
StandardNamingStrategy.class
|
||||
);
|
||||
|
||||
strategySelector.registerStrategyImplementor(
|
||||
ImplicitDatabaseObjectNamingStrategy.class,
|
||||
SingleNamingStrategy.STRATEGY_NAME,
|
||||
SingleNamingStrategy.class
|
||||
);
|
||||
|
||||
strategySelector.registerStrategyImplementor(
|
||||
|
@ -232,12 +238,6 @@ public class StrategySelectorBuilder {
|
|||
LegacyNamingStrategy.STRATEGY_NAME,
|
||||
LegacyNamingStrategy.class
|
||||
);
|
||||
|
||||
strategySelector.registerStrategyImplementor(
|
||||
ImplicitDatabaseObjectNamingStrategy.class,
|
||||
LegacyPreferGeneratorNameNamingStrategy.STRATEGY_NAME,
|
||||
LegacyPreferGeneratorNameNamingStrategy.class
|
||||
);
|
||||
}
|
||||
|
||||
private void addCacheKeysFactories(StrategySelectorImpl strategySelector) {
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.hibernate.CustomEntityDirtinessStrategy;
|
|||
import org.hibernate.Incubating;
|
||||
import org.hibernate.Interceptor;
|
||||
import org.hibernate.SessionFactoryObserver;
|
||||
import org.hibernate.boot.registry.selector.spi.StrategySelector;
|
||||
import org.hibernate.id.enhanced.ImplicitDatabaseObjectNamingStrategy;
|
||||
import org.hibernate.cache.spi.TimestampsCacheFactory;
|
||||
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
|
||||
|
@ -780,9 +781,17 @@ public interface AvailableSettings {
|
|||
* An implicit naming-strategy for database structures (tables, sequences) related
|
||||
* to identifier-generators
|
||||
*
|
||||
* @see ImplicitDatabaseObjectNamingStrategy
|
||||
* Resolution uses the {@link org.hibernate.boot.registry.selector.spi.StrategySelector}
|
||||
* service and accepts any of the forms discussed on
|
||||
* {@link StrategySelector#resolveDefaultableStrategy}.
|
||||
*
|
||||
* @incubating `ImplicitDatabaseObjectNamingStrategy` is considered incubating
|
||||
* The recognized short names being:<ul>
|
||||
* <li>{@value org.hibernate.id.enhanced.SingleNamingStrategy#STRATEGY_NAME}</li>
|
||||
* <li>{@value org.hibernate.id.enhanced.LegacyNamingStrategy#STRATEGY_NAME}</li>
|
||||
* <li>{@value org.hibernate.id.enhanced.StandardNamingStrategy#STRATEGY_NAME}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @see ImplicitDatabaseObjectNamingStrategy
|
||||
*/
|
||||
@Incubating
|
||||
String ID_DB_STRUCTURE_NAMING_STRATEGY = "hibernate.id.db_structure_naming_strategy";
|
||||
|
|
|
@ -8,46 +8,124 @@ package org.hibernate.id.enhanced;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
* Naming strategy which implements the behavior of older versions of
|
||||
* Hibernate, for the most part.
|
||||
*
|
||||
* For sequences (including forced-table sequences):<ol>
|
||||
* <li>
|
||||
* If {@value SequenceStyleGenerator#CONFIG_SEQUENCE_PER_ENTITY_SUFFIX} is specified,
|
||||
* a name composed of the "base" name with the specified suffix. The base name
|
||||
* depends on the usage of the generator, but is generally the root entity-name if
|
||||
* applied to an entity identifier or the table we are generating values for
|
||||
* </li>
|
||||
* <li>
|
||||
* If annotations are used and {@link GeneratedValue#generator()} is specified,
|
||||
* its value is used as the sequence name
|
||||
* </li>
|
||||
* <li>
|
||||
* Fall back is to use {@value DEF_SEQUENCE}
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* For tables:<ol>
|
||||
* <li>
|
||||
* If annotations are used and {@link GeneratedValue#generator()} is specified,
|
||||
* its value is used as the table name
|
||||
* </li>
|
||||
* <li>
|
||||
* Fall back is to use {@value TableGenerator#DEF_TABLE}
|
||||
* </li>
|
||||
* </ol>
|
||||
*/
|
||||
public class LegacyNamingStrategy implements ImplicitDatabaseObjectNamingStrategy {
|
||||
public static final String STRATEGY_NAME = "legacy";
|
||||
|
||||
@Override
|
||||
public QualifiedName determineSequenceName(
|
||||
Identifier catalogName,
|
||||
Identifier schemaName,
|
||||
Map<?, ?> configValues,
|
||||
ServiceRegistry serviceRegistry) {
|
||||
final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
|
||||
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( DEF_SEQUENCE )
|
||||
jdbcEnvironment.getIdentifierHelper().toIdentifier( sequenceName )
|
||||
);
|
||||
}
|
||||
|
||||
private String implicitSequenceName(Map<?, ?> configValues) {
|
||||
final String explicitSuffix = ConfigurationHelper.getString( CONFIG_SEQUENCE_PER_ENTITY_SUFFIX, configValues );
|
||||
|
||||
if ( StringHelper.isNotEmpty( explicitSuffix ) ) {
|
||||
// an "implicit name suffix" was specified
|
||||
final String rootTableName = ConfigurationHelper.getString( PersistentIdentifierGenerator.TABLE, configValues );
|
||||
final String base = ConfigurationHelper.getString( IMPLICIT_NAME_BASE, configValues, rootTableName );
|
||||
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 = implicitTableName( 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( DEF_TABLE )
|
||||
jdbcEnvironment.getIdentifierHelper().toIdentifier( implicitName )
|
||||
);
|
||||
}
|
||||
|
||||
private String implicitTableName(Map<?, ?> configValues) {
|
||||
final String annotationName = ConfigurationHelper.getString( IdentifierGenerator.GENERATOR_NAME, configValues );
|
||||
if ( StringHelper.isNotEmpty( annotationName ) ) {
|
||||
return annotationName;
|
||||
}
|
||||
|
||||
return DEF_TABLE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,108 +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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
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<ol>
|
||||
* <li>{@link org.hibernate.id.enhanced.TableGenerator#TABLE_PARAM}</li>
|
||||
* </ol>
|
||||
*
|
||||
*
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
}
|
|
@ -339,7 +339,7 @@ public class SequenceStyleGenerator
|
|||
}
|
||||
return globalSetting;
|
||||
},
|
||||
StandardDatabaseObjectNamingStrategy.class::getName
|
||||
StandardNamingStrategy.class::getName
|
||||
);
|
||||
|
||||
final ImplicitDatabaseObjectNamingStrategy namingStrategy = strategySelector.resolveStrategy(
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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.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.service.ServiceRegistry;
|
||||
|
||||
import static org.hibernate.id.enhanced.TableGenerator.DEF_TABLE;
|
||||
|
||||
/**
|
||||
* ImplicitDatabaseObjectNamingStrategy using a single structure for
|
||||
* all implicit names:<ul>
|
||||
* <li>{@value ImplicitDatabaseObjectNamingStrategy#DEF_SEQUENCE} for sequences</li>
|
||||
* <li>{@value TableGenerator#DEF_TABLE} for tables</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
public class SingleNamingStrategy implements ImplicitDatabaseObjectNamingStrategy {
|
||||
public static final String STRATEGY_NAME = "single";
|
||||
|
||||
@Override
|
||||
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( DEF_SEQUENCE )
|
||||
);
|
||||
}
|
||||
|
||||
public QualifiedName determineTableName(
|
||||
Identifier catalogName,
|
||||
Identifier schemaName,
|
||||
Map<?, ?> configValues,
|
||||
ServiceRegistry serviceRegistry) {
|
||||
final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
|
||||
return new QualifiedNameParser.NameParts(
|
||||
catalogName,
|
||||
schemaName,
|
||||
jdbcEnvironment.getIdentifierHelper().toIdentifier( DEF_TABLE )
|
||||
);
|
||||
}
|
||||
}
|
|
@ -8,6 +8,8 @@ package org.hibernate.id.enhanced;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.boot.model.naming.Identifier;
|
||||
import org.hibernate.boot.model.relational.QualifiedName;
|
||||
|
@ -26,10 +28,41 @@ import static org.hibernate.id.enhanced.SequenceStyleGenerator.DEF_SEQUENCE_SUFF
|
|||
import static org.hibernate.id.enhanced.TableGenerator.DEF_TABLE;
|
||||
|
||||
/**
|
||||
* Hibernate's standard implicit naming strategy for identifier sequences and tables.
|
||||
*
|
||||
* For sequences (including forced-table sequences):<ol>
|
||||
* <li>
|
||||
* If {@value SequenceStyleGenerator#CONFIG_SEQUENCE_PER_ENTITY_SUFFIX} is specified,
|
||||
* a name composed of the "base" name with the specified suffix. The base name
|
||||
* depends on the usage of the generator, but is generally the root entity-name if
|
||||
* applied to an entity identifier or the table we are generating values for
|
||||
* </li>
|
||||
* <li>
|
||||
* If annotations are used and {@link GeneratedValue#generator()} is specified,
|
||||
* its value is used as the sequence name
|
||||
* </li>
|
||||
* <li>
|
||||
* If the "base" name is known, use that
|
||||
* </li>
|
||||
* <li>
|
||||
* Throw an exception
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* For tables:<ol>
|
||||
* <li>
|
||||
* If annotations are used and {@link GeneratedValue#generator()} is specified,
|
||||
* its value is used as the table name
|
||||
* </li>
|
||||
* <li>
|
||||
* Fall back is to use {@value TableGenerator#DEF_TABLE}
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class StandardDatabaseObjectNamingStrategy implements ImplicitDatabaseObjectNamingStrategy {
|
||||
public static final String STRATEGY_NAME = "default";
|
||||
public class StandardNamingStrategy implements ImplicitDatabaseObjectNamingStrategy {
|
||||
public static final String STRATEGY_NAME = "standard";
|
||||
|
||||
@Override
|
||||
public QualifiedName determineSequenceName(
|
||||
|
@ -40,7 +73,7 @@ public class StandardDatabaseObjectNamingStrategy implements ImplicitDatabaseObj
|
|||
final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
|
||||
|
||||
final String rootTableName = ConfigurationHelper.getString( PersistentIdentifierGenerator.TABLE, configValues );
|
||||
final String implicitName = implicitName( rootTableName, configValues, serviceRegistry );
|
||||
final String implicitName = implicitSequenceName( rootTableName, configValues, serviceRegistry );
|
||||
|
||||
if ( implicitName.contains( "." ) ) {
|
||||
return QualifiedNameParser.INSTANCE.parse( implicitName );
|
||||
|
@ -53,7 +86,7 @@ public class StandardDatabaseObjectNamingStrategy implements ImplicitDatabaseObj
|
|||
);
|
||||
}
|
||||
|
||||
private static String implicitName(
|
||||
private static String implicitSequenceName(
|
||||
String rootTableName,
|
||||
Map<?, ?> configValues,
|
||||
ServiceRegistry serviceRegistry) {
|
|
@ -411,7 +411,7 @@ public class TableGenerator implements PersistentIdentifierGenerator {
|
|||
}
|
||||
return globalSetting;
|
||||
},
|
||||
StandardDatabaseObjectNamingStrategy.class::getName
|
||||
StandardNamingStrategy.class::getName
|
||||
);
|
||||
|
||||
final ImplicitDatabaseObjectNamingStrategy namingStrategy = strategySelector.resolveStrategy(
|
||||
|
|
|
@ -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.orm.test.namingstrategy;
|
||||
package org.hibernate.orm.test.id.enhanced;
|
||||
|
||||
import java.util.Map;
|
||||
import jakarta.persistence.Basic;
|
||||
|
@ -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.ImplicitDatabaseObjectNamingStrategyTests$Strategy"
|
||||
value = "org.hibernate.orm.test.id.enhanced.CustomNamingStrategyTests$Strategy"
|
||||
)
|
||||
)
|
||||
@DomainModel( annotatedClasses = ImplicitDatabaseObjectNamingStrategyTests.TheEntity.class )
|
||||
public class ImplicitDatabaseObjectNamingStrategyTests {
|
||||
@DomainModel( annotatedClasses = CustomNamingStrategyTests.TheEntity.class )
|
||||
public class CustomNamingStrategyTests {
|
||||
|
||||
@Test
|
||||
public void testIt(DomainModelScope domainModelScope, ServiceRegistryScope serviceRegistryScope) {
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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 org.hibernate.boot.registry.selector.spi.StrategySelector;
|
||||
import org.hibernate.id.enhanced.ImplicitDatabaseObjectNamingStrategy;
|
||||
import org.hibernate.id.enhanced.LegacyNamingStrategy;
|
||||
import org.hibernate.id.enhanced.SingleNamingStrategy;
|
||||
import org.hibernate.id.enhanced.StandardNamingStrategy;
|
||||
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@ServiceRegistry
|
||||
public class NamingStrategySelectorTests {
|
||||
@Test
|
||||
void testShortNames(ServiceRegistryScope scope) {
|
||||
scope.withService( StrategySelector.class, (service) -> {
|
||||
final ImplicitDatabaseObjectNamingStrategy single = service.resolveStrategy( ImplicitDatabaseObjectNamingStrategy.class, SingleNamingStrategy.STRATEGY_NAME );
|
||||
assertThat( single ).isInstanceOf( SingleNamingStrategy.class );
|
||||
|
||||
final ImplicitDatabaseObjectNamingStrategy legacy = service.resolveStrategy( ImplicitDatabaseObjectNamingStrategy.class, LegacyNamingStrategy.STRATEGY_NAME );
|
||||
assertThat( legacy ).isInstanceOf( LegacyNamingStrategy.class );
|
||||
|
||||
final ImplicitDatabaseObjectNamingStrategy standard = service.resolveStrategy( ImplicitDatabaseObjectNamingStrategy.class, StandardNamingStrategy.STRATEGY_NAME );
|
||||
assertThat( standard ).isInstanceOf( StandardNamingStrategy.class );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMissing(ServiceRegistryScope scope) {
|
||||
scope.withService( StrategySelector.class, (service) -> {
|
||||
final ImplicitDatabaseObjectNamingStrategy single = service.resolveStrategy( ImplicitDatabaseObjectNamingStrategy.class, null );
|
||||
assertThat( single ).isNull();
|
||||
} );
|
||||
}
|
||||
}
|
|
@ -22,10 +22,10 @@ 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.SingleNamingStrategy;
|
||||
import org.hibernate.id.enhanced.SequenceStructure;
|
||||
import org.hibernate.id.enhanced.SequenceStyleGenerator;
|
||||
import org.hibernate.id.enhanced.StandardDatabaseObjectNamingStrategy;
|
||||
import org.hibernate.id.enhanced.StandardNamingStrategy;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
|
||||
|
@ -44,77 +44,77 @@ 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" );
|
||||
verify( TestEntity.class, StandardNamingStrategy.STRATEGY_NAME, "TestEntity_SEQ" );
|
||||
verify( TestEntity.class, StandardNamingStrategy.class.getName(), "TestEntity_SEQ" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSequenceNameHibernateSequenceStrategy() {
|
||||
verify( TestEntity.class, SingleNamingStrategy.STRATEGY_NAME, "hibernate_sequence" );
|
||||
verify( TestEntity.class, SingleNamingStrategy.class.getName(), "hibernate_sequence" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSequenceNamePreferGeneratorNameStrategy() {
|
||||
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" );
|
||||
verify( TestEntity2.class, StandardNamingStrategy.STRATEGY_NAME, "table_generator" );
|
||||
verify( TestEntity2.class, StandardNamingStrategy.class.getName(), "table_generator" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoGeneratorHibernateSequenceStrategy() {
|
||||
verify( TestEntity2.class, LegacyNamingStrategy.STRATEGY_NAME, "hibernate_sequence" );
|
||||
verify( TestEntity2.class, LegacyNamingStrategy.class.getName(), "hibernate_sequence" );
|
||||
verify( TestEntity2.class, SingleNamingStrategy.STRATEGY_NAME, "hibernate_sequence" );
|
||||
verify( TestEntity2.class, SingleNamingStrategy.class.getName(), "hibernate_sequence" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoGeneratorPreferGeneratorNameStrategy() {
|
||||
verify( TestEntity2.class, LegacyPreferGeneratorNameNamingStrategy.STRATEGY_NAME, "table_generator" );
|
||||
verify( TestEntity2.class, LegacyPreferGeneratorNameNamingStrategy.class.getName(), "table_generator" );
|
||||
verify( TestEntity2.class, LegacyNamingStrategy.STRATEGY_NAME, "table_generator" );
|
||||
verify( TestEntity2.class, LegacyNamingStrategy.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" );
|
||||
verify( TestEntity3.class, StandardNamingStrategy.STRATEGY_NAME, "table_generator" );
|
||||
verify( TestEntity3.class, StandardNamingStrategy.class.getName(), "table_generator" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeneratorWithoutSequenceNameHibernateSequenceStrategy() {
|
||||
verify( TestEntity3.class, LegacyNamingStrategy.STRATEGY_NAME, "hibernate_sequence" );
|
||||
verify( TestEntity3.class, LegacyNamingStrategy.class.getName(), "hibernate_sequence" );
|
||||
verify( TestEntity3.class, SingleNamingStrategy.STRATEGY_NAME, "hibernate_sequence" );
|
||||
verify( TestEntity3.class, SingleNamingStrategy.class.getName(), "hibernate_sequence" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeneratorWithoutSequenceNamePreferGeneratorNameStrategy() {
|
||||
verify( TestEntity3.class, LegacyPreferGeneratorNameNamingStrategy.STRATEGY_NAME, "table_generator" );
|
||||
verify( TestEntity3.class, LegacyPreferGeneratorNameNamingStrategy.class.getName(), "table_generator" );
|
||||
verify( TestEntity3.class, LegacyNamingStrategy.STRATEGY_NAME, "table_generator" );
|
||||
verify( TestEntity3.class, LegacyNamingStrategy.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" );
|
||||
verify( TestEntity4.class, StandardNamingStrategy.STRATEGY_NAME, "test_sequence" );
|
||||
verify( TestEntity4.class, StandardNamingStrategy.class.getName(), "test_sequence" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeneratorWithSequenceNameHibernateSequenceStrategy() {
|
||||
verify( TestEntity4.class, LegacyNamingStrategy.STRATEGY_NAME, "test_sequence" );
|
||||
verify( TestEntity4.class, LegacyNamingStrategy.class.getName(), "test_sequence" );
|
||||
verify( TestEntity4.class, SingleNamingStrategy.STRATEGY_NAME, "test_sequence" );
|
||||
verify( TestEntity4.class, SingleNamingStrategy.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" );
|
||||
verify( TestEntity4.class, LegacyNamingStrategy.STRATEGY_NAME, "test_sequence" );
|
||||
verify( TestEntity4.class, LegacyNamingStrategy.class.getName(), "test_sequence" );
|
||||
}
|
||||
|
||||
private void verify(Class<?> entityType, String expectedName) {
|
||||
|
|
|
@ -9,7 +9,6 @@ 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;
|
||||
|
||||
|
@ -21,8 +20,8 @@ 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.id.enhanced.SingleNamingStrategy;
|
||||
import org.hibernate.id.enhanced.StandardNamingStrategy;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.mapping.Table;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
|
@ -87,18 +86,18 @@ public class TableNamingStrategyTest {
|
|||
|
||||
private void verifyStandardStrategy(Class<?> entityClass, String expectedName) {
|
||||
verify( entityClass, expectedName );
|
||||
verify( entityClass, StandardDatabaseObjectNamingStrategy.STRATEGY_NAME, expectedName );
|
||||
verify( entityClass, StandardDatabaseObjectNamingStrategy.class.getName(), expectedName );
|
||||
verify( entityClass, StandardNamingStrategy.STRATEGY_NAME, expectedName );
|
||||
verify( entityClass, StandardNamingStrategy.class.getName(), expectedName );
|
||||
}
|
||||
|
||||
private void verifyLegacyStrategy(Class<?> entityClass, String expectedName) {
|
||||
verify( entityClass, LegacyNamingStrategy.STRATEGY_NAME, expectedName );
|
||||
verify( entityClass, LegacyNamingStrategy.class.getName(), expectedName );
|
||||
verify( entityClass, SingleNamingStrategy.STRATEGY_NAME, expectedName );
|
||||
verify( entityClass, SingleNamingStrategy.class.getName(), expectedName );
|
||||
}
|
||||
|
||||
private void verifyLegacyPreferStrategy(Class<?> entityClass, String expectedName) {
|
||||
verify( entityClass, LegacyPreferGeneratorNameNamingStrategy.STRATEGY_NAME, expectedName );
|
||||
verify( entityClass, LegacyPreferGeneratorNameNamingStrategy.class.getName(), expectedName );
|
||||
verify( entityClass, LegacyNamingStrategy.STRATEGY_NAME, expectedName );
|
||||
verify( entityClass, LegacyNamingStrategy.class.getName(), expectedName );
|
||||
}
|
||||
|
||||
private void verify(Class<?> entityType, String expectedName) {
|
||||
|
|
|
@ -99,22 +99,20 @@ to define custom generators to use for identifier generation.
|
|||
|
||||
// todo (6.0 - @Steve - need to add content about this to the User Guide
|
||||
|
||||
[[id-sequence-generation]]
|
||||
== Id Sequence and Table generation
|
||||
[[id-sequence-table-name]]
|
||||
== Implicit Identifier Sequence and Table Name
|
||||
|
||||
For a sequence id generation strategy Hibernate 6.0 by default does not create anymore a single sequence named `hibernate_sequence` but it creates one sequence for each entity.
|
||||
The way in which Hibernate determines implicit names for sequences and tables associated with identifier
|
||||
generation has changed in 6.0 which may affect migrating applications.
|
||||
|
||||
In order to maintain backward compatibility a new setting `hibernate.id.db_structure_naming_strategy`
|
||||
has been introduced.
|
||||
To help with backwards compatibility, or to apply any general naming strategy, 6.0 introduces the
|
||||
`org.hibernate.id.enhanced.ImplicitDatabaseObjectNamingStrategy` contract which can be specified using
|
||||
the `hibernate.id.db_structure_naming_strategy` setting. See discussion at
|
||||
link:{javadocsBase}/org/hibernate/cfg/AvailableSettings.html#ID_DB_STRUCTURE_NAMING_STRATEGY
|
||||
|
||||
For backwards compatibility, use either `hibernate.id.db_structure_naming_strategy=single` or
|
||||
`hibernate.id.db_structure_naming_strategy=legacy` depending on needs
|
||||
|
||||
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.LegacyPreferGeneratorNameNamingStrategy
|
||||
```
|
||||
otherwise
|
||||
```
|
||||
hibernate.id.db_structure_naming_strategy=org.hibernate.id.enhanced.LegacyNamingStrategy
|
||||
```
|
||||
|
||||
[[type]]
|
||||
== Type system
|
||||
|
|
Loading…
Reference in New Issue