HHH-18139 clean up / reorg of generator binding related code

Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
Gavin King 2024-05-30 11:15:03 +02:00 committed by Steve Ebersole
parent 58f555ab39
commit 1d7ed0e84d
20 changed files with 710 additions and 851 deletions

View File

@ -1,193 +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.boot.internal;
import java.util.UUID;
import org.hibernate.boot.model.IdentifierGeneratorDefinition;
import org.hibernate.id.IncrementGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.UUIDGenerator;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.TableGenerator;
import jakarta.persistence.UniqueConstraint;
/**
* Interpretations related to value generators based on the {@linkplain GenerationType strategy/type}
*
* @author Steve Ebersole
*/
public class GenerationStrategyInterpreter {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( GenerationStrategyInterpreter.class );
public static final GenerationStrategyInterpreter STRATEGY_INTERPRETER = new GenerationStrategyInterpreter();
public interface GeneratorNameDeterminationContext {
/**
* The Java type of the attribute defining the id whose value is to
* be generated.
*/
Class<?> getIdType();
/**
* The {@link GeneratedValue#generator()} name.
*/
String getGeneratedValueGeneratorName();
}
private GenerationStrategyInterpreter() {
}
public String determineGeneratorName(GenerationType generationType, GeneratorNameDeterminationContext context) {
switch ( generationType ) {
case IDENTITY: {
return "identity";
}
case SEQUENCE: {
return SequenceStyleGenerator.class.getName();
}
case TABLE: {
return org.hibernate.id.enhanced.TableGenerator.class.getName();
}
case UUID: {
return UUIDGenerator.class.getName();
}
case AUTO: {
if ( UUID.class.isAssignableFrom( context.getIdType() ) ) {
return UUIDGenerator.class.getName();
}
else if ( "increment".equalsIgnoreCase( context.getGeneratedValueGeneratorName() ) ) {
// special case for @GeneratedValue(name="increment")
// for some reason we consider there to be an implicit
// generator named 'increment' (doesn't seem very useful)
return IncrementGenerator.class.getName();
}
else {
return SequenceStyleGenerator.class.getName();
}
}
default: {
throw new UnsupportedOperationException( "Unsupported generation type:" + generationType );
}
}
}
public void interpretTableGenerator(
TableGenerator tableGeneratorAnnotation,
IdentifierGeneratorDefinition.Builder definitionBuilder) {
definitionBuilder.setName( tableGeneratorAnnotation.name() );
definitionBuilder.setStrategy( org.hibernate.id.enhanced.TableGenerator.class.getName() );
definitionBuilder.addParam( org.hibernate.id.enhanced.TableGenerator.CONFIG_PREFER_SEGMENT_PER_ENTITY, "true" );
final String catalog = tableGeneratorAnnotation.catalog();
if ( StringHelper.isNotEmpty( catalog ) ) {
definitionBuilder.addParam( PersistentIdentifierGenerator.CATALOG, catalog );
}
final String schema = tableGeneratorAnnotation.schema();
if ( StringHelper.isNotEmpty( schema ) ) {
definitionBuilder.addParam( PersistentIdentifierGenerator.SCHEMA, schema );
}
final String table = tableGeneratorAnnotation.table();
if ( StringHelper.isNotEmpty( table ) ) {
definitionBuilder.addParam( org.hibernate.id.enhanced.TableGenerator.TABLE_PARAM, table );
}
final String pkColumnName = tableGeneratorAnnotation.pkColumnName();
if ( StringHelper.isNotEmpty( pkColumnName ) ) {
definitionBuilder.addParam(
org.hibernate.id.enhanced.TableGenerator.SEGMENT_COLUMN_PARAM,
pkColumnName
);
}
final String pkColumnValue = tableGeneratorAnnotation.pkColumnValue();
if ( StringHelper.isNotEmpty( pkColumnValue ) ) {
definitionBuilder.addParam(
org.hibernate.id.enhanced.TableGenerator.SEGMENT_VALUE_PARAM,
pkColumnValue
);
}
final String valueColumnName = tableGeneratorAnnotation.valueColumnName();
if ( StringHelper.isNotEmpty( valueColumnName ) ) {
definitionBuilder.addParam(
org.hibernate.id.enhanced.TableGenerator.VALUE_COLUMN_PARAM,
valueColumnName
);
}
final String options = tableGeneratorAnnotation.options();
if ( StringHelper.isNotEmpty( options ) ) {
definitionBuilder.addParam(
PersistentIdentifierGenerator.OPTIONS,
options
);
}
definitionBuilder.addParam(
org.hibernate.id.enhanced.TableGenerator.INCREMENT_PARAM,
String.valueOf( tableGeneratorAnnotation.allocationSize() )
);
// See comment on HHH-4884 wrt initialValue. Basically initialValue is really the stated value + 1
definitionBuilder.addParam(
org.hibernate.id.enhanced.TableGenerator.INITIAL_PARAM,
String.valueOf( tableGeneratorAnnotation.initialValue() + 1 )
);
// TODO : implement unique-constraint support
final UniqueConstraint[] uniqueConstraints = tableGeneratorAnnotation.uniqueConstraints();
if ( CollectionHelper.isNotEmpty( uniqueConstraints ) ) {
LOG.ignoringTableGeneratorConstraints( tableGeneratorAnnotation.name() );
}
}
public void interpretSequenceGenerator(
SequenceGenerator sequenceGeneratorAnnotation,
IdentifierGeneratorDefinition.Builder definitionBuilder) {
definitionBuilder.setName( sequenceGeneratorAnnotation.name() );
definitionBuilder.setStrategy( SequenceStyleGenerator.class.getName() );
final String catalog = sequenceGeneratorAnnotation.catalog();
if ( StringHelper.isNotEmpty( catalog ) ) {
definitionBuilder.addParam( PersistentIdentifierGenerator.CATALOG, catalog );
}
final String schema = sequenceGeneratorAnnotation.schema();
if ( StringHelper.isNotEmpty( schema ) ) {
definitionBuilder.addParam( PersistentIdentifierGenerator.SCHEMA, schema );
}
final String sequenceName = sequenceGeneratorAnnotation.sequenceName();
if ( StringHelper.isNotEmpty( sequenceName ) ) {
definitionBuilder.addParam( SequenceStyleGenerator.SEQUENCE_PARAM, sequenceName );
}
definitionBuilder.addParam(
SequenceStyleGenerator.INCREMENT_PARAM,
String.valueOf( sequenceGeneratorAnnotation.allocationSize() )
);
definitionBuilder.addParam(
SequenceStyleGenerator.INITIAL_PARAM,
String.valueOf( sequenceGeneratorAnnotation.initialValue() )
);
final String options = sequenceGeneratorAnnotation.options();
if ( StringHelper.isNotEmpty( options ) ) {
definitionBuilder.addParam( PersistentIdentifierGenerator.OPTIONS, options );
}
}
}

View File

@ -6,26 +6,27 @@
*/
package org.hibernate.boot.model;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import jakarta.persistence.GenerationType;
import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure;
import org.hibernate.Internal;
import org.hibernate.boot.internal.GenerationStrategyInterpreter;
import org.hibernate.boot.models.annotations.internal.SequenceGeneratorJpaAnnotation;
import org.hibernate.boot.models.annotations.internal.TableGeneratorJpaAnnotation;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.models.spi.TypeDetails;
import jakarta.persistence.GenerationType;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonMap;
import static java.util.Collections.unmodifiableMap;
import static org.hibernate.boot.internal.GenerationStrategyInterpreter.STRATEGY_INTERPRETER;
import static org.hibernate.boot.model.internal.GeneratorParameters.interpretSequenceGenerator;
import static org.hibernate.boot.model.internal.GeneratorParameters.interpretTableGenerator;
import static org.hibernate.boot.model.internal.GeneratorStrategies.generatorStrategy;
import static org.hibernate.boot.models.JpaAnnotations.SEQUENCE_GENERATOR;
import static org.hibernate.boot.models.JpaAnnotations.TABLE_GENERATOR;
import static org.hibernate.internal.util.collections.CollectionHelper.isEmpty;
@ -93,7 +94,7 @@ public class IdentifierGeneratorDefinition implements Serializable {
@Internal
public static IdentifierGeneratorDefinition createImplicit(
String name,
Class<?> idType,
TypeDetails idType,
String generatorName,
GenerationType generationType) {
// If we were unable to locate an actual matching named generator assume
@ -104,49 +105,29 @@ public class IdentifierGeneratorDefinition implements Serializable {
}
switch ( generationType ) {
case SEQUENCE: {
case SEQUENCE:
return buildSequenceGeneratorDefinition( name );
}
case TABLE: {
case TABLE:
return buildTableGeneratorDefinition( name );
}
case IDENTITY: {
case IDENTITY:
throw new AnnotationException(
"@GeneratedValue annotation specified 'strategy=IDENTITY' and 'generator'"
+ " but the generator name is unnecessary"
);
}
case UUID: {
case UUID:
throw new AnnotationException(
"@GeneratedValue annotation specified 'strategy=UUID' and 'generator'"
+ " but the generator name is unnecessary"
);
}
case AUTO: {
final String strategyName = STRATEGY_INTERPRETER.determineGeneratorName(
generationType,
new GenerationStrategyInterpreter.GeneratorNameDeterminationContext() {
@Override
public Class<?> getIdType() {
return idType;
}
@Override
public String getGeneratedValueGeneratorName() {
return generatorName;
}
}
);
case AUTO:
return new IdentifierGeneratorDefinition(
name,
strategyName,
Collections.singletonMap( IdentifierGenerator.GENERATOR_NAME, name )
generatorStrategy( generationType, generatorName, idType ),
singletonMap( IdentifierGenerator.GENERATOR_NAME, name )
);
}
default:
throw new AssertionFailure( "unknown generator type: " + generationType );
}
throw new AssertionFailure( "unknown generator type: " + generationType );
}
private static IdentifierGeneratorDefinition buildTableGeneratorDefinition(String name) {
@ -155,7 +136,7 @@ public class IdentifierGeneratorDefinition implements Serializable {
if ( StringHelper.isNotEmpty( name ) ) {
tableGeneratorUsage.name( name );
}
STRATEGY_INTERPRETER.interpretTableGenerator( tableGeneratorUsage, builder );
interpretTableGenerator( tableGeneratorUsage, builder );
return builder.build();
}
@ -165,7 +146,7 @@ public class IdentifierGeneratorDefinition implements Serializable {
if ( StringHelper.isNotEmpty( name ) ) {
sequenceGeneratorUsage.name( name );
}
STRATEGY_INTERPRETER.interpretSequenceGenerator( sequenceGeneratorUsage, builder );
interpretSequenceGenerator( sequenceGeneratorUsage, builder );
return builder.build();
}

View File

@ -19,12 +19,10 @@ import org.hibernate.annotations.EmbeddableInstantiatorRegistration;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.FetchProfile;
import org.hibernate.annotations.FetchProfile.FetchOverride;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Imported;
import org.hibernate.annotations.JavaTypeRegistration;
import org.hibernate.annotations.JdbcTypeRegistration;
import org.hibernate.annotations.TypeRegistration;
import org.hibernate.boot.internal.GenerationStrategyInterpreter;
import org.hibernate.boot.model.IdentifierGeneratorDefinition;
import org.hibernate.boot.model.convert.spi.RegisteredConversion;
import org.hibernate.boot.models.HibernateAnnotations;
@ -46,15 +44,14 @@ import jakarta.persistence.FetchType;
import jakarta.persistence.Inheritance;
import jakarta.persistence.InheritanceType;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.Table;
import jakarta.persistence.TableGenerator;
import static org.hibernate.boot.model.internal.AnnotatedClassType.EMBEDDABLE;
import static org.hibernate.boot.model.internal.AnnotatedClassType.ENTITY;
import static org.hibernate.boot.model.internal.FilterDefBinder.bindFilterDefs;
import static org.hibernate.boot.model.internal.GeneratorBinder.buildGenerators;
import static org.hibernate.boot.model.internal.GeneratorBinder.buildIdGenerator;
import static org.hibernate.boot.model.internal.GeneratorParameters.interpretSequenceGenerator;
import static org.hibernate.boot.model.internal.GeneratorParameters.interpretTableGenerator;
import static org.hibernate.boot.model.internal.InheritanceState.getInheritanceStateOfSuperEntity;
import static org.hibernate.boot.model.internal.InheritanceState.getSuperclassInheritanceState;
import static org.hibernate.internal.CoreLogging.messageLogger;
@ -82,10 +79,7 @@ public final class AnnotationBinder {
globalRegistrations.getSequenceGeneratorRegistrations().forEach( (name, generatorRegistration) -> {
final IdentifierGeneratorDefinition.Builder definitionBuilder = new IdentifierGeneratorDefinition.Builder();
GenerationStrategyInterpreter.STRATEGY_INTERPRETER.interpretSequenceGenerator(
generatorRegistration.configuration(),
definitionBuilder
);
interpretSequenceGenerator( generatorRegistration.configuration(), definitionBuilder );
final IdentifierGeneratorDefinition idGenDef = definitionBuilder.build();
if ( LOG.isTraceEnabled() ) {
LOG.tracef( "Adding global sequence generator with name: %s", name );
@ -95,10 +89,7 @@ public final class AnnotationBinder {
globalRegistrations.getTableGeneratorRegistrations().forEach( (name, generatorRegistration) -> {
final IdentifierGeneratorDefinition.Builder definitionBuilder = new IdentifierGeneratorDefinition.Builder();
GenerationStrategyInterpreter.STRATEGY_INTERPRETER.interpretTableGenerator(
generatorRegistration.configuration(),
definitionBuilder
);
interpretTableGenerator( generatorRegistration.configuration(), definitionBuilder );
final IdentifierGeneratorDefinition idGenDef = definitionBuilder.build();
if ( LOG.isTraceEnabled() ) {
LOG.tracef( "Adding global table generator with name: %s", name );
@ -128,17 +119,20 @@ public final class AnnotationBinder {
} );
}
private static SourceModelBuildingContext sourceContext(MetadataBuildingContext context) {
return context.getMetadataCollector().getSourceModelBuildingContext();
}
public static void bindPackage(ClassLoaderService cls, String packageName, MetadataBuildingContext context) {
final Package pack = cls.packageForNameOrNull( packageName );
if ( pack == null ) {
return;
}
final ClassDetails packageInfoClassDetails = context.getMetadataCollector()
.getSourceModelBuildingContext()
.getClassDetailsRegistry()
.resolveClassDetails( pack.getName() + ".package-info" );
final ClassDetails packageInfoClassDetails =
sourceContext( context ).getClassDetailsRegistry()
.resolveClassDetails( pack.getName() + ".package-info" );
handleIdGenerators( packageInfoClassDetails, context );
buildGenerators( packageInfoClassDetails, context );
bindTypeDescriptorRegistrations( packageInfoClassDetails, context );
bindEmbeddableInstantiatorRegistrations( packageInfoClassDetails, context );
@ -146,50 +140,17 @@ public final class AnnotationBinder {
bindCompositeUserTypeRegistrations( packageInfoClassDetails, context );
bindConverterRegistrations( packageInfoClassDetails, context );
bindGenericGenerators( packageInfoClassDetails, context );
bindQueries( packageInfoClassDetails, context );
bindFilterDefs( packageInfoClassDetails, context );
}
private static void handleIdGenerators(ClassDetails packageInfoClassDetails, MetadataBuildingContext context) {
final SourceModelBuildingContext sourceModelContext = context.getMetadataCollector().getSourceModelBuildingContext();
packageInfoClassDetails.forEachAnnotationUsage( SequenceGenerator.class, sourceModelContext, (usage) -> {
IdentifierGeneratorDefinition idGen = buildIdGenerator( usage, context );
context.getMetadataCollector().addIdentifierGenerator( idGen );
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Add sequence generator with name: {0}", idGen.getName() );
}
} );
packageInfoClassDetails.forEachAnnotationUsage( TableGenerator.class, sourceModelContext, (usage) -> {
IdentifierGeneratorDefinition idGen = buildIdGenerator( usage, context );
context.getMetadataCollector().addIdentifierGenerator( idGen );
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Add table generator with name: {0}", idGen.getName() );
}
} );
}
private static void bindGenericGenerators(AnnotationTarget annotatedElement, MetadataBuildingContext context) {
final SourceModelBuildingContext sourceModelContext = context.getMetadataCollector().getSourceModelBuildingContext();
annotatedElement.forEachAnnotationUsage( GenericGenerator.class, sourceModelContext, (usage) -> {
bindGenericGenerator( usage, context );
} );
}
private static void bindGenericGenerator(GenericGenerator def, MetadataBuildingContext context) {
context.getMetadataCollector().addIdentifierGenerator( buildIdGenerator( def, context ) );
}
public static void bindQueries(AnnotationTarget annotationTarget, MetadataBuildingContext context) {
bindNamedJpaQueries( annotationTarget, context );
bindNamedHibernateQueries( annotationTarget, context );
}
private static void bindNamedHibernateQueries(AnnotationTarget annotationTarget, MetadataBuildingContext context) {
final SourceModelBuildingContext sourceModelContext = context.getMetadataCollector().getSourceModelBuildingContext();
final SourceModelBuildingContext sourceModelContext = sourceContext( context );
annotationTarget.forEachRepeatedAnnotationUsages(
HibernateAnnotations.NAMED_QUERY,
@ -205,7 +166,7 @@ public final class AnnotationBinder {
}
private static void bindNamedJpaQueries(AnnotationTarget annotationTarget, MetadataBuildingContext context) {
final SourceModelBuildingContext sourceModelContext = context.getMetadataCollector().getSourceModelBuildingContext();
final SourceModelBuildingContext sourceModelContext = sourceContext( context );
annotationTarget.forEachRepeatedAnnotationUsages(
JpaAnnotations.SQL_RESULT_SET_MAPPING,
@ -293,11 +254,12 @@ public final class AnnotationBinder {
private static void bindTypeDescriptorRegistrations(
AnnotationTarget annotatedElement,
MetadataBuildingContext context) {
final ManagedBeanRegistry managedBeanRegistry = context.getBootstrapContext()
.getServiceRegistry()
.getService( ManagedBeanRegistry.class );
final ManagedBeanRegistry managedBeanRegistry =
context.getBootstrapContext().getServiceRegistry()
.getService( ManagedBeanRegistry.class );
final SourceModelBuildingContext sourceModelContext = sourceContext( context );
final SourceModelBuildingContext sourceModelContext = context.getMetadataCollector().getSourceModelBuildingContext();
annotatedElement.forEachAnnotationUsage( JavaTypeRegistration.class, sourceModelContext, (usage) -> {
handleJavaTypeRegistration( context, managedBeanRegistry, usage );
} );
@ -343,8 +305,7 @@ public final class AnnotationBinder {
private static void bindEmbeddableInstantiatorRegistrations(
AnnotationTarget annotatedElement,
MetadataBuildingContext context) {
final SourceModelBuildingContext sourceModelContext = context.getMetadataCollector().getSourceModelBuildingContext();
annotatedElement.forEachAnnotationUsage( EmbeddableInstantiatorRegistration.class, sourceModelContext, (usage) -> {
annotatedElement.forEachAnnotationUsage( EmbeddableInstantiatorRegistration.class, sourceContext( context ), (usage) -> {
handleEmbeddableInstantiatorRegistration( context, usage );
} );
}
@ -361,9 +322,7 @@ public final class AnnotationBinder {
private static void bindCompositeUserTypeRegistrations(
AnnotationTarget annotatedElement,
MetadataBuildingContext context) {
final SourceModelBuildingContext sourceModelContext = context.getMetadataCollector().getSourceModelBuildingContext();
annotatedElement.forEachAnnotationUsage( CompositeTypeRegistration.class, sourceModelContext, (usage) -> {
annotatedElement.forEachAnnotationUsage( CompositeTypeRegistration.class, sourceContext( context ), (usage) -> {
handleCompositeUserTypeRegistration( context, usage );
} );
}
@ -371,8 +330,7 @@ public final class AnnotationBinder {
private static void bindUserTypeRegistrations(
AnnotationTarget annotatedElement,
MetadataBuildingContext context) {
final SourceModelBuildingContext sourceModelContext = context.getMetadataCollector().getSourceModelBuildingContext();
annotatedElement.forEachAnnotationUsage( TypeRegistration.class, sourceModelContext, (usage) -> {
annotatedElement.forEachAnnotationUsage( TypeRegistration.class, sourceContext( context ), (usage) -> {
handleUserTypeRegistration( context, usage );
} );
}
@ -400,7 +358,7 @@ public final class AnnotationBinder {
}
private static void bindConverterRegistrations(AnnotationTarget container, MetadataBuildingContext context) {
final SourceModelBuildingContext sourceModelContext = context.getMetadataCollector().getSourceModelBuildingContext();
final SourceModelBuildingContext sourceModelContext = sourceContext( context );
container.forEachAnnotationUsage( ConverterRegistration.class, sourceModelContext, (usage) -> {
handleConverterRegistration( usage, context );
} );
@ -430,8 +388,7 @@ public final class AnnotationBinder {
}
private static void bindFetchProfiles(AnnotationTarget annotatedElement, MetadataBuildingContext context) {
final SourceModelBuildingContext sourceModelContext = context.getMetadataCollector().getSourceModelBuildingContext();
annotatedElement.forEachAnnotationUsage( FetchProfile.class, sourceModelContext, (usage) -> {
annotatedElement.forEachAnnotationUsage( FetchProfile.class, sourceContext( context ), (usage) -> {
bindFetchProfile( usage, context );
} );
}

View File

@ -58,7 +58,6 @@ import org.hibernate.models.spi.ClassDetailsRegistry;
import org.hibernate.models.spi.MemberDetails;
import org.hibernate.models.spi.SourceModelBuildingContext;
import org.hibernate.models.spi.TypeDetails;
import org.hibernate.models.spi.TypeDetailsHelper;
import org.hibernate.type.descriptor.java.JavaType;
import jakarta.persistence.ConstraintMode;
@ -76,6 +75,7 @@ import static org.hibernate.internal.util.StringHelper.isEmpty;
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
import static org.hibernate.internal.util.StringHelper.qualifier;
import static org.hibernate.internal.util.StringHelper.qualify;
import static org.hibernate.models.spi.TypeDetailsHelper.resolveRawClass;
import static org.hibernate.property.access.spi.BuiltInPropertyAccessStrategies.EMBEDDED;
import static org.hibernate.property.access.spi.BuiltInPropertyAccessStrategies.NOOP;
import static org.hibernate.property.access.spi.BuiltInPropertyAccessStrategies.interpret;
@ -586,8 +586,8 @@ public class BinderHelper {
*/
public static Property findPropertyByName(PersistentClass associatedClass, String propertyName) {
Property property = null;
Property idProperty = associatedClass.getIdentifierProperty();
String idName = idProperty == null ? null : idProperty.getName();
final Property idProperty = associatedClass.getIdentifierProperty();
final String idName = idProperty == null ? null : idProperty.getName();
try {
if ( isEmpty( propertyName ) || propertyName.equals( idName ) ) {
//default to id
@ -598,9 +598,9 @@ public class BinderHelper {
property = idProperty;
propertyName = propertyName.substring( idName.length() + 1 );
}
StringTokenizer st = new StringTokenizer( propertyName, ".", false );
while ( st.hasMoreElements() ) {
String element = (String) st.nextElement();
final StringTokenizer tokens = new StringTokenizer( propertyName, ".", false );
while ( tokens.hasMoreElements() ) {
String element = (String) tokens.nextElement();
if ( property == null ) {
property = associatedClass.getProperty( element );
}
@ -619,9 +619,9 @@ public class BinderHelper {
if ( associatedClass.getIdentifierMapper() == null ) {
return null;
}
StringTokenizer st = new StringTokenizer( propertyName, ".", false );
while ( st.hasMoreElements() ) {
String element = (String) st.nextElement();
final StringTokenizer tokens = new StringTokenizer( propertyName, ".", false );
while ( tokens.hasMoreElements() ) {
final String element = (String) tokens.nextElement();
if ( property == null ) {
property = associatedClass.getIdentifierMapper().getProperty( element );
}
@ -646,15 +646,14 @@ public class BinderHelper {
public static Property findPropertyByName(Component component, String propertyName) {
Property property = null;
try {
if ( propertyName == null
|| propertyName.length() == 0) {
if ( isEmpty( propertyName ) ) {
// Do not expect to use a primary key for this case
return null;
}
else {
StringTokenizer st = new StringTokenizer( propertyName, ".", false );
while ( st.hasMoreElements() ) {
String element = (String) st.nextElement();
final StringTokenizer tokens = new StringTokenizer( propertyName, ".", false );
while ( tokens.hasMoreElements() ) {
final String element = (String) tokens.nextElement();
if ( property == null ) {
property = component.getProperty( element );
}
@ -673,9 +672,9 @@ public class BinderHelper {
if ( component.getOwner().getIdentifierMapper() == null ) {
return null;
}
StringTokenizer st = new StringTokenizer( propertyName, ".", false );
while ( st.hasMoreElements() ) {
String element = (String) st.nextElement();
final StringTokenizer tokens = new StringTokenizer( propertyName, ".", false );
while ( tokens.hasMoreElements() ) {
final String element = (String) tokens.nextElement();
if ( property == null ) {
property = component.getOwner().getIdentifierMapper().getProperty( element );
}
@ -834,14 +833,16 @@ public class BinderHelper {
MemberDetails property,
Consumer<AnyDiscriminatorValue> consumer,
SourceModelBuildingContext sourceModelContext) {
final AnyDiscriminatorValues valuesAnn = property.locateAnnotationUsage( AnyDiscriminatorValues.class, sourceModelContext );
final AnyDiscriminatorValues valuesAnn =
property.locateAnnotationUsage( AnyDiscriminatorValues.class, sourceModelContext );
if ( valuesAnn != null ) {
final AnyDiscriminatorValue[] nestedList = valuesAnn.value();
ArrayHelper.forEach( nestedList, consumer );
return;
}
final AnyDiscriminatorValue valueAnn = property.locateAnnotationUsage( AnyDiscriminatorValue.class, sourceModelContext );
final AnyDiscriminatorValue valueAnn =
property.locateAnnotationUsage( AnyDiscriminatorValue.class, sourceModelContext );
if ( valueAnn != null ) {
consumer.accept( valueAnn );
}
@ -957,10 +958,10 @@ public class BinderHelper {
return renderCascadeTypeList( cascadeTypes );
}
private static EnumSet<CascadeType> convertToHibernateCascadeType(jakarta.persistence.CascadeType[] ejbCascades) {
private static EnumSet<CascadeType> convertToHibernateCascadeType(jakarta.persistence.CascadeType[] cascades) {
final EnumSet<CascadeType> cascadeTypes = EnumSet.noneOf( CascadeType.class );
if ( ejbCascades != null ) {
for ( jakarta.persistence.CascadeType cascade: ejbCascades ) {
if ( cascades != null ) {
for ( jakarta.persistence.CascadeType cascade: cascades ) {
cascadeTypes.add( convertCascadeType( cascade ) );
}
}
@ -1028,7 +1029,7 @@ public class BinderHelper {
break;
}
}
return cascade.length() > 0 ? cascade.substring( 1 ) : "none";
return cascade.isEmpty() ? "none" : cascade.substring(1);
}
private static void warnAboutDeprecatedCascadeType(CascadeType cascadeType) {
@ -1053,18 +1054,17 @@ public class BinderHelper {
return context.getBootstrapContext().getJpaCompliance().isGlobalGeneratorScopeEnabled();
}
static boolean isCompositeId(ClassDetails entityClass, MemberDetails idProperty) {
return entityClass.hasDirectAnnotationUsage( Embeddable.class )
static boolean isCompositeId(ClassDetails idClass, MemberDetails idProperty) {
return idClass.hasDirectAnnotationUsage( Embeddable.class )
|| idProperty.hasDirectAnnotationUsage( EmbeddedId.class );
}
public static boolean isDefault(ClassDetails clazz, MetadataBuildingContext context) {
public static boolean isDefault(ClassDetails clazz) {
return clazz == ClassDetails.VOID_CLASS_DETAILS;
}
public static boolean isDefault(TypeDetails clazz, MetadataBuildingContext context) {
final ClassDetails rawClassDetails = TypeDetailsHelper.resolveRawClass( clazz );
return rawClassDetails == ClassDetails.VOID_CLASS_DETAILS;
public static boolean isDefault(TypeDetails clazz) {
return resolveRawClass( clazz ) == ClassDetails.VOID_CLASS_DETAILS;
}
public static void checkMappedByType(
@ -1121,7 +1121,7 @@ public class BinderHelper {
else {
final ConstraintMode mode = foreignKey.value();
return mode == NO_CONSTRAINT
|| mode == PROVIDER_DEFAULT && noConstraintByDefault;
|| mode == PROVIDER_DEFAULT && noConstraintByDefault;
}
}

View File

@ -1614,7 +1614,7 @@ public abstract class CollectionBinder {
}
TypeDetails getElementType() {
if ( isDefault( targetEntity, buildingContext ) ) {
if ( isDefault( targetEntity ) ) {
if ( collectionElementType != null ) {
return collectionElementType;
}

View File

@ -6,15 +6,20 @@
*/
package org.hibernate.boot.model.internal;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import jakarta.persistence.Column;
import jakarta.persistence.Convert;
import jakarta.persistence.DiscriminatorColumn;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Embeddable;
import jakarta.persistence.Embedded;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import org.hibernate.AnnotationException;
import org.hibernate.annotations.DiscriminatorFormula;
import org.hibernate.annotations.Instantiator;
@ -46,32 +51,26 @@ import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
import org.hibernate.type.BasicType;
import org.hibernate.usertype.CompositeUserType;
import jakarta.persistence.Column;
import jakarta.persistence.Convert;
import jakarta.persistence.DiscriminatorColumn;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Embeddable;
import jakarta.persistence.Embedded;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import static org.hibernate.boot.model.internal.AnnotatedDiscriminatorColumn.DEFAULT_DISCRIMINATOR_COLUMN_NAME;
import static org.hibernate.boot.model.internal.AnnotatedDiscriminatorColumn.buildDiscriminatorColumn;
import static org.hibernate.boot.model.internal.DialectOverridesAnnotationHelper.getOverridableAnnotation;
import static org.hibernate.boot.model.internal.BinderHelper.getPath;
import static org.hibernate.boot.model.internal.BinderHelper.getPropertyOverriddenByMapperOrMapsId;
import static org.hibernate.boot.model.internal.BinderHelper.getRelativePath;
import static org.hibernate.boot.model.internal.BinderHelper.hasToOneAnnotation;
import static org.hibernate.boot.model.internal.BinderHelper.isGlobalGeneratorNameGlobal;
import static org.hibernate.boot.model.internal.DialectOverridesAnnotationHelper.getOverridableAnnotation;
import static org.hibernate.boot.model.internal.GeneratorBinder.buildGenerators;
import static org.hibernate.boot.model.internal.GeneratorBinder.generatorType;
import static org.hibernate.boot.model.internal.GeneratorBinder.makeIdGenerator;
import static org.hibernate.boot.model.internal.GeneratorStrategies.generatorStrategy;
import static org.hibernate.boot.model.internal.PropertyBinder.addElementsOfClass;
import static org.hibernate.boot.model.internal.PropertyBinder.processElementAnnotations;
import static org.hibernate.boot.model.internal.PropertyHolderBuilder.buildPropertyHolder;
@ -813,15 +812,15 @@ public class EmbeddableBinder {
private static void processGeneratedId(MetadataBuildingContext context, Component component, MemberDetails property) {
final GeneratedValue generatedValue = property.getDirectAnnotationUsage( GeneratedValue.class );
final String generatorType = generatedValue != null
? generatorType( generatedValue, property.getType().determineRawClass(), context )
: GeneratorBinder.ASSIGNED_GENERATOR_NAME;
final String generator = generatedValue != null ? generatedValue.generator() : "";
final String generatorType =
generatorStrategy( generatedValue.strategy(), generatedValue.generator(), property.getType() );
final String generator = generatedValue.generator();
final SimpleValue value = (SimpleValue) component.getProperty( property.getName()).getValue();
if ( isGlobalGeneratorNameGlobal( context ) ) {
buildGenerators( property, context );
context.getMetadataCollector().addSecondPass( new IdGeneratorResolverSecondPass(
(SimpleValue) component.getProperty( property.getName() ).getValue(),
value,
property,
generatorType,
generator,
@ -835,7 +834,7 @@ public class EmbeddableBinder {
}
else {
makeIdGenerator(
(SimpleValue) component.getProperty( property.getName() ).getValue(),
value,
property,
generatorType,
generator,

View File

@ -8,7 +8,6 @@ package org.hibernate.boot.model.internal;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@ -156,7 +155,6 @@ import static org.hibernate.boot.model.internal.BinderHelper.toAliasTableMap;
import static org.hibernate.boot.model.internal.DialectOverridesAnnotationHelper.getOverridableAnnotation;
import static org.hibernate.boot.model.internal.DialectOverridesAnnotationHelper.getOverrideAnnotation;
import static org.hibernate.boot.model.internal.EmbeddableBinder.fillEmbeddable;
import static org.hibernate.boot.model.internal.GeneratorBinder.makeIdGenerator;
import static org.hibernate.boot.model.internal.InheritanceState.getInheritanceStateOfSuperEntity;
import static org.hibernate.boot.model.internal.PropertyBinder.addElementsOfClass;
import static org.hibernate.boot.model.internal.PropertyBinder.hasIdAnnotation;
@ -749,8 +747,6 @@ public class EntityBinder {
rootClass.setIdentifier( id );
handleIdGenerator( inferredData, buildingContext, id );
rootClass.setEmbeddedIdentifier( inferredData.getPropertyType() == null );
propertyHolder.setInIdClass( null );
@ -758,28 +754,6 @@ public class EntityBinder {
return id;
}
private static void handleIdGenerator(PropertyData inferredData, MetadataBuildingContext buildingContext, Component id) {
if ( buildingContext.getBootstrapContext().getJpaCompliance().isGlobalGeneratorScopeEnabled() ) {
buildingContext.getMetadataCollector().addSecondPass( new IdGeneratorResolverSecondPass(
id,
inferredData.getAttributeMember(),
GeneratorBinder.ASSIGNED_GENERATOR_NAME,
"",
buildingContext
) );
}
else {
makeIdGenerator(
id,
inferredData.getAttributeMember(),
GeneratorBinder.ASSIGNED_GENERATOR_NAME,
"",
buildingContext,
Collections.emptyMap()
);
}
}
private void handleSecondaryTables() {
annotatedClass.forEachRepeatedAnnotationUsages( JpaAnnotations.SECONDARY_TABLE, getSourceModelContext(), (usage) -> {
addSecondaryTable( usage, null, false );

View File

@ -6,29 +6,23 @@
*/
package org.hibernate.boot.model.internal;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.TableGenerator;
import jakarta.persistence.Version;
import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure;
import org.hibernate.MappingException;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.IdGeneratorType;
import org.hibernate.annotations.ValueGenerationType;
import org.hibernate.boot.internal.GenerationStrategyInterpreter;
import org.hibernate.boot.model.IdentifierGeneratorDefinition;
import org.hibernate.boot.model.relational.ExportableProducer;
import org.hibernate.boot.model.source.internal.hbm.MappingDocument;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.spi.InFlightMetadataCollector;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.config.spi.StandardConverters;
import org.hibernate.boot.spi.PropertyData;
import org.hibernate.generator.AnnotationBasedGenerator;
import org.hibernate.generator.Assigned;
import org.hibernate.generator.BeforeExecutionGenerator;
@ -36,27 +30,15 @@ import org.hibernate.generator.Generator;
import org.hibernate.generator.GeneratorCreationContext;
import org.hibernate.generator.OnExecutionGenerator;
import org.hibernate.id.Configurable;
import org.hibernate.id.ForeignGenerator;
import org.hibernate.id.GUIDGenerator;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.IdentityGenerator;
import org.hibernate.id.IncrementGenerator;
import org.hibernate.id.OptimizableGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.SelectGenerator;
import org.hibernate.id.UUIDGenerator;
import org.hibernate.id.UUIDHexGenerator;
import org.hibernate.id.enhanced.LegacyNamingStrategy;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.id.enhanced.SingleNamingStrategy;
import org.hibernate.internal.CoreLogging;
import org.hibernate.mapping.Column;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.mapping.GeneratorCreator;
import org.hibernate.mapping.RootClass;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Table;
import org.hibernate.models.spi.AnnotationTarget;
import org.hibernate.models.spi.ClassDetails;
import org.hibernate.models.spi.MemberDetails;
import org.hibernate.models.spi.SourceModelBuildingContext;
import org.hibernate.resource.beans.container.spi.BeanContainer;
@ -65,19 +47,25 @@ import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.Type;
import org.jboss.logging.Logger;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.TableGenerator;
import jakarta.persistence.Version;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import static java.util.Collections.emptyMap;
import static org.hibernate.boot.internal.GenerationStrategyInterpreter.STRATEGY_INTERPRETER;
import static org.hibernate.boot.model.internal.AnnotationHelper.extractParameterMap;
import static org.hibernate.boot.model.internal.BinderHelper.isCompositeId;
import static org.hibernate.boot.model.internal.BinderHelper.getPath;
import static org.hibernate.boot.model.internal.BinderHelper.isGlobalGeneratorNameGlobal;
import static org.hibernate.boot.model.internal.GeneratorParameters.collectParameters;
import static org.hibernate.boot.model.internal.GeneratorParameters.interpretSequenceGenerator;
import static org.hibernate.boot.model.internal.GeneratorParameters.interpretTableGenerator;
import static org.hibernate.boot.model.internal.GeneratorStrategies.generatorClass;
import static org.hibernate.boot.model.internal.GeneratorStrategies.generatorStrategy;
import static org.hibernate.internal.util.StringHelper.qualify;
import static org.hibernate.resource.beans.internal.Helper.allowExtensionsInCdi;
/**
@ -87,7 +75,7 @@ import static org.hibernate.resource.beans.internal.Helper.allowExtensionsInCdi;
*/
public class GeneratorBinder {
private static final Logger LOG = CoreLogging.logger( GeneratorBinder.class );
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( GeneratorBinder.class );
public static final String ASSIGNED_GENERATOR_NAME = "assigned";
public static final GeneratorCreator ASSIGNED_IDENTIFIER_GENERATOR_CREATOR =
@ -103,144 +91,7 @@ public class GeneratorBinder {
};
/**
* Interpret an "old" generator strategy name as a {@link Generator} class.
*/
private static Class<? extends Generator> generatorClass(String strategy, SimpleValue idValue) {
if ( "native".equals(strategy) ) {
strategy =
idValue.getMetadata().getDatabase().getDialect()
.getNativeIdentifierGeneratorStrategy();
}
switch (strategy) {
case "assigned":
return org.hibernate.id.Assigned.class;
case "enhanced-sequence":
case "sequence":
return SequenceStyleGenerator.class;
case "enhanced-table":
case "table":
return org.hibernate.id.enhanced.TableGenerator.class;
case "identity":
return IdentityGenerator.class;
case "increment":
return IncrementGenerator.class;
case "foreign":
return ForeignGenerator.class;
case "uuid":
case "uuid.hex":
return UUIDHexGenerator.class;
case "uuid2":
return UUIDGenerator.class;
case "select":
return SelectGenerator.class;
case "guid":
return GUIDGenerator.class;
}
final Class<? extends Generator> clazz =
idValue.getServiceRegistry().requireService( ClassLoaderService.class )
.classForName( strategy );
if ( !Generator.class.isAssignableFrom( clazz ) ) {
// in principle, this shouldn't happen, since @GenericGenerator
// constrains the type to subtypes of Generator
throw new MappingException( clazz.getName() + " does not implement 'Generator'" );
}
return clazz;
}
/**
* Collect the parameters which should be passed to
* {@link Configurable#configure(Type, Properties, ServiceRegistry)}.
*/
public static Properties collectParameters(
SimpleValue identifierValue,
Dialect dialect,
RootClass rootClass,
Map<String, Object> configuration) {
final ConfigurationService configService =
identifierValue.getMetadata().getMetadataBuildingOptions().getServiceRegistry()
.requireService( ConfigurationService.class );
final Properties params = new Properties();
// default initial value and allocation size per-JPA defaults
params.setProperty( OptimizableGenerator.INITIAL_PARAM,
String.valueOf( OptimizableGenerator.DEFAULT_INITIAL_VALUE ) );
params.setProperty( OptimizableGenerator.INCREMENT_PARAM,
String.valueOf( defaultIncrement( configService ) ) );
//init the table here instead of earlier, so that we can get a quoted table name
//TODO: would it be better to simply pass the qualified table name, instead of
// splitting it up into schema/catalog/table names
final String tableName = identifierValue.getTable().getQuotedName( dialect );
params.setProperty( PersistentIdentifierGenerator.TABLE, tableName );
//pass the column name (a generated id almost always has a single column)
final Column column = (Column) identifierValue.getSelectables().get(0);
final String columnName = column.getQuotedName( dialect );
params.setProperty( PersistentIdentifierGenerator.PK, columnName );
//pass the entity-name, if not a collection-id
if ( rootClass != null ) {
params.setProperty( IdentifierGenerator.ENTITY_NAME, rootClass.getEntityName() );
params.setProperty( IdentifierGenerator.JPA_ENTITY_NAME, rootClass.getJpaEntityName() );
// The table name is not really a good default for subselect entities,
// so use the JPA entity name which is short
params.setProperty( OptimizableGenerator.IMPLICIT_NAME_BASE,
identifierValue.getTable().isSubselect()
? rootClass.getJpaEntityName()
: identifierValue.getTable().getName() );
params.setProperty( PersistentIdentifierGenerator.TABLES,
identityTablesString( dialect, rootClass ) );
}
else {
params.setProperty( PersistentIdentifierGenerator.TABLES, tableName );
params.setProperty( OptimizableGenerator.IMPLICIT_NAME_BASE, tableName );
}
params.put( IdentifierGenerator.CONTRIBUTOR_NAME,
identifierValue.getBuildingContext().getCurrentContributorName() );
final Map<String, Object> settings = configService.getSettings();
if ( settings.containsKey( AvailableSettings.PREFERRED_POOLED_OPTIMIZER ) ) {
params.put( AvailableSettings.PREFERRED_POOLED_OPTIMIZER,
settings.get( AvailableSettings.PREFERRED_POOLED_OPTIMIZER ) );
}
params.putAll( configuration );
return params;
}
private static String identityTablesString(Dialect dialect, RootClass rootClass) {
final StringBuilder tables = new StringBuilder();
for ( Table table : rootClass.getIdentityTables() ) {
tables.append( table.getQuotedName( dialect ) );
if ( !tables.isEmpty() ) {
tables.append( ", " );
}
}
return tables.toString();
}
private static int defaultIncrement(ConfigurationService configService) {
final String idNamingStrategy =
configService.getSetting( AvailableSettings.ID_DB_STRUCTURE_NAMING_STRATEGY,
StandardConverters.STRING, null );
if ( LegacyNamingStrategy.STRATEGY_NAME.equals( idNamingStrategy )
|| LegacyNamingStrategy.class.getName().equals( idNamingStrategy )
|| SingleNamingStrategy.STRATEGY_NAME.equals( idNamingStrategy )
|| SingleNamingStrategy.class.getName().equals( idNamingStrategy ) ) {
return 1;
}
else {
return OptimizableGenerator.DEFAULT_INCREMENT_SIZE;
}
}
/**
* Apply an id generation strategy and parameters to the
* given {@link SimpleValue} which represents an identifier.
* Create a generator, based on a {@link GeneratedValue} annotation.
*/
public static void makeIdGenerator(
SimpleValue id,
@ -252,20 +103,15 @@ public class GeneratorBinder {
//generator settings
final Map<String,Object> configuration = new HashMap<>();
//always settable
configuration.put( IdentifierGenerator.GENERATOR_NAME, generatorName );
configuration.put( PersistentIdentifierGenerator.TABLE, id.getTable().getName() );
if ( id.getColumnSpan() == 1 ) {
configuration.put( PersistentIdentifierGenerator.PK, id.getColumns().get(0).getName() );
}
// YUCK! but cannot think of a clean way to do this given the string-config based scheme
configuration.put( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER, context.getObjectNameNormalizer() );
configuration.put( IdentifierGenerator.GENERATOR_NAME, generatorName );
final String generatorStrategy =
determineStrategy( idAttributeMember, generatorType, generatorName, context, localGenerators, configuration );
setGeneratorCreator( id, configuration, generatorStrategy, beanContainer( context ) );
setGeneratorCreator( id, configuration, generatorStrategy, context );
}
private static String determineStrategy(
@ -300,22 +146,6 @@ public class GeneratorBinder {
}
}
/**
* apply an id generator to a SimpleValue
*/
public static void makeIdGenerator(
SimpleValue id,
MemberDetails idAttributeMember,
String generatorType,
String generatorName,
MetadataBuildingContext buildingContext,
IdentifierGeneratorDefinition foreignKGeneratorDefinition) {
makeIdGenerator( id, idAttributeMember, generatorType, generatorName, buildingContext,
foreignKGeneratorDefinition != null
? Map.of( foreignKGeneratorDefinition.getName(), foreignKGeneratorDefinition )
: null );
}
private static IdentifierGeneratorDefinition makeIdentifierGeneratorDefinition(
String name,
MemberDetails idAttributeMember,
@ -338,13 +168,12 @@ public class GeneratorBinder {
final GeneratedValue generatedValue = idAttributeMember.getDirectAnnotationUsage( GeneratedValue.class );
if ( generatedValue == null ) {
// this should really never happen, but it's easy to protect against it...
return new IdentifierGeneratorDefinition(ASSIGNED_GENERATOR_NAME, ASSIGNED_GENERATOR_NAME);
throw new AssertionFailure( "No @GeneratedValue annotation" );
}
return IdentifierGeneratorDefinition.createImplicit(
name,
idAttributeMember.getType().determineRawClass().toJavaClass(),
idAttributeMember.getType(),
generatedValue.generator(),
interpretGenerationType( generatedValue )
);
@ -356,6 +185,10 @@ public class GeneratorBinder {
return strategy == null ? GenerationType.AUTO : strategy;
}
/**
* Build any generators declared using {@link TableGenerator}, {@link SequenceGenerator},
* and {@link GenericGenerator} annotations of the given program element.
*/
public static Map<String, IdentifierGeneratorDefinition> buildGenerators(
AnnotationTarget annotatedElement,
MetadataBuildingContext context) {
@ -364,19 +197,19 @@ public class GeneratorBinder {
final Map<String, IdentifierGeneratorDefinition> generators = new HashMap<>();
annotatedElement.forEachAnnotationUsage( TableGenerator.class, sourceModelContext, (usage) -> {
IdentifierGeneratorDefinition idGenerator = buildIdGenerator( usage, context );
IdentifierGeneratorDefinition idGenerator = buildTableIdGenerator( usage );
generators.put( idGenerator.getName(), idGenerator );
metadataCollector.addIdentifierGenerator( idGenerator );
} );
annotatedElement.forEachAnnotationUsage( SequenceGenerator.class, sourceModelContext, (usage) -> {
IdentifierGeneratorDefinition idGenerator = buildIdGenerator( usage, context );
IdentifierGeneratorDefinition idGenerator = buildSequenceIdGenerator( usage );
generators.put( idGenerator.getName(), idGenerator );
metadataCollector.addIdentifierGenerator( idGenerator );
} );
annotatedElement.forEachAnnotationUsage( GenericGenerator.class, sourceModelContext, (usage) -> {
final IdentifierGeneratorDefinition idGenerator = buildIdGenerator( usage, context );
final IdentifierGeneratorDefinition idGenerator = buildIdGenerator( usage );
generators.put( idGenerator.getName(), idGenerator );
metadataCollector.addIdentifierGenerator( idGenerator );
} );
@ -384,87 +217,38 @@ public class GeneratorBinder {
return generators;
}
static String generatorType(
MetadataBuildingContext context,
ClassDetails entityXClass,
boolean isComponent,
GeneratedValue generatedValue) {
if ( isComponent ) {
//a component must not have any generator
return ASSIGNED_GENERATOR_NAME;
}
else {
return generatedValue == null ? ASSIGNED_GENERATOR_NAME : generatorType( generatedValue, entityXClass, context );
}
}
private static IdentifierGeneratorDefinition buildIdGenerator(GenericGenerator generatorAnnotation) {
final IdentifierGeneratorDefinition.Builder definitionBuilder =
new IdentifierGeneratorDefinition.Builder();
definitionBuilder.setName( generatorAnnotation.name() );
final Class<? extends Generator> generatorClass = generatorAnnotation.type();
final String strategy =
generatorClass.equals( Generator.class )
? generatorAnnotation.strategy()
: generatorClass.getName();
definitionBuilder.setStrategy( strategy );
definitionBuilder.addParams( extractParameterMap( generatorAnnotation.parameters() ) );
static String generatorType(
GeneratedValue generatedValue,
final ClassDetails javaClass,
MetadataBuildingContext context) {
return STRATEGY_INTERPRETER.determineGeneratorName(
generatedValue.strategy(),
new GenerationStrategyInterpreter.GeneratorNameDeterminationContext() {
Class<?> javaType = null;
@Override
public Class<?> getIdType() {
if ( javaType == null ) {
javaType = javaClass.toJavaClass();
}
return javaType;
}
@Override
public String getGeneratedValueGeneratorName() {
return generatedValue.generator();
}
}
);
}
static IdentifierGeneratorDefinition buildIdGenerator(
Annotation generatorAnnotation,
MetadataBuildingContext context) {
if ( generatorAnnotation == null ) {
return null;
}
final IdentifierGeneratorDefinition.Builder definitionBuilder = new IdentifierGeneratorDefinition.Builder();
if ( generatorAnnotation instanceof TableGenerator tableGenerator ) {
STRATEGY_INTERPRETER.interpretTableGenerator( tableGenerator, definitionBuilder );
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Add table generator with name: {0}", definitionBuilder.getName() );
}
}
else if ( generatorAnnotation instanceof SequenceGenerator sequenceGenerator ) {
STRATEGY_INTERPRETER.interpretSequenceGenerator( sequenceGenerator, definitionBuilder );
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Add sequence generator with name: {0}", definitionBuilder.getName() );
}
}
else if ( generatorAnnotation instanceof GenericGenerator genericGenerator ) {
definitionBuilder.setName( genericGenerator.name() );
final Class<? extends Generator> generatorClass = genericGenerator.type();
final String strategy =
generatorClass.equals( Generator.class )
? genericGenerator.strategy()
: generatorClass.getName();
definitionBuilder.setStrategy( strategy );
definitionBuilder.addParams( extractParameterMap( genericGenerator.parameters() ) );
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Add generic generator with name: {0}", definitionBuilder.getName() );
}
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Added generator with name: {0}, strategy: {0}",
definitionBuilder.getName(), definitionBuilder.getStrategy() );
}
return definitionBuilder.build();
}
static IdentifierGeneratorDefinition buildSequenceIdGenerator(SequenceGenerator generatorAnnotation) {
if ( generatorAnnotation == null ) {
return null;
}
private static IdentifierGeneratorDefinition buildSequenceIdGenerator(SequenceGenerator generatorAnnotation) {
final IdentifierGeneratorDefinition.Builder definitionBuilder = new IdentifierGeneratorDefinition.Builder();
STRATEGY_INTERPRETER.interpretSequenceGenerator( generatorAnnotation, definitionBuilder );
interpretSequenceGenerator( generatorAnnotation, definitionBuilder );
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Add sequence generator with name: {0}", definitionBuilder.getName() );
}
return definitionBuilder.build();
}
private static IdentifierGeneratorDefinition buildTableIdGenerator(TableGenerator generatorAnnotation) {
final IdentifierGeneratorDefinition.Builder definitionBuilder = new IdentifierGeneratorDefinition.Builder();
interpretTableGenerator( generatorAnnotation, definitionBuilder );
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Add sequence generator with name: {0}", definitionBuilder.getName() );
}
@ -494,20 +278,16 @@ public class GeneratorBinder {
}
/**
* In case the given annotation is a value generator annotation, the corresponding value generation strategy to be
* applied to the given property is returned, {@code null} otherwise.
* Instantiates the given generator annotation type, initializing it with the given instance of the corresponding
* generator annotation and the property's type.
* Return a {@link GeneratorCreator} for an attribute annotated
* with a {@linkplain ValueGenerationType generator annotation}.
*/
static GeneratorCreator generatorCreator(
private static GeneratorCreator generatorCreator(
MemberDetails memberDetails,
Annotation annotation,
BeanContainer beanContainer) {
final Class<? extends Annotation> annotationType = annotation.annotationType();
final ValueGenerationType generatorAnnotation = annotationType.getAnnotation( ValueGenerationType.class );
if ( generatorAnnotation == null ) {
return null;
}
assert generatorAnnotation != null;
final Class<? extends Generator> generatorClass = generatorAnnotation.generatedBy();
checkGeneratorClass( generatorClass );
checkGeneratorInterfaces( generatorClass );
@ -527,15 +307,19 @@ public class GeneratorBinder {
};
}
static GeneratorCreator identifierGeneratorCreator(
/**
* Return a {@link GeneratorCreator} for an id attribute annotated
* with an {@linkplain IdGeneratorType id generator annotation}.
*/
private static GeneratorCreator identifierGeneratorCreator(
MemberDetails idAttributeMember,
Annotation annotation,
SimpleValue identifierValue,
BeanContainer beanContainer) {
final Class<? extends Annotation> annotationType = annotation.annotationType();
final IdGeneratorType idGeneratorType = annotationType.getAnnotation( IdGeneratorType.class );
assert idGeneratorType != null;
final Class<? extends Generator> generatorClass = idGeneratorType.value();
final IdGeneratorType idGeneratorAnnotation = annotationType.getAnnotation( IdGeneratorType.class );
assert idGeneratorAnnotation != null;
final Class<? extends Generator> generatorClass = idGeneratorAnnotation.value();
checkGeneratorClass( generatorClass );
return creationContext -> {
final Generator generator =
@ -562,7 +346,7 @@ public class GeneratorBinder {
* @param beanContainer an optional {@code BeanContainer}
* @param generatorClass a class which implements {@code Generator}
*/
private static <C> Generator instantiateGenerator(
private static Generator instantiateGenerator(
Annotation annotation,
BeanContainer beanContainer,
GeneratorCreationContext creationContext,
@ -807,23 +591,26 @@ public class GeneratorBinder {
}
}
static void createIdGenerator(
/**
* Create a generator, based on a {@link GeneratedValue} annotation.
*/
private static void createIdGenerator(
SimpleValue idValue,
Map<String, IdentifierGeneratorDefinition> classGenerators,
MetadataBuildingContext context,
ClassDetails entityClass,
MemberDetails idAttributeMember) {
MemberDetails idMember) {
//manage composite related metadata
//guess if its a component and find id data access (property, field etc)
final GeneratedValue generatedValue = idAttributeMember.getDirectAnnotationUsage( GeneratedValue.class );
final String generatorType = generatorType( context, entityClass, isCompositeId( entityClass, idAttributeMember ), generatedValue );
final String generatorName = generatedValue == null ? "" : generatedValue.generator();
final GeneratedValue generatedValue = idMember.getDirectAnnotationUsage( GeneratedValue.class );
final String generatorType =
generatorStrategy( generatedValue.strategy(), generatedValue.generator(), idMember.getType() );
final String generatorName = generatedValue.generator();
if ( isGlobalGeneratorNameGlobal( context ) ) {
buildGenerators( idAttributeMember, context );
buildGenerators( idMember, context );
context.getMetadataCollector()
.addSecondPass( new IdGeneratorResolverSecondPass(
idValue,
idAttributeMember,
idMember,
generatorType,
generatorName,
context
@ -832,8 +619,8 @@ public class GeneratorBinder {
else {
//clone classGenerator and override with local values
final Map<String, IdentifierGeneratorDefinition> generators = new HashMap<>( classGenerators );
generators.putAll( buildGenerators( idAttributeMember, context ) );
makeIdGenerator( idValue, idAttributeMember, generatorType, generatorName, context, generators );
generators.putAll( buildGenerators( idMember, context ) );
makeIdGenerator( idValue, idMember, generatorType, generatorName, context, generators );
}
}
@ -846,14 +633,14 @@ public class GeneratorBinder {
final MappingDocument sourceDocument,
IdentifierGeneratorDefinition definition,
SimpleValue identifierValue,
MetadataBuildingContext buildingContext) {
MetadataBuildingContext context) {
if ( definition != null ) {
final Map<String,Object> configuration = new HashMap<>();
// see if the specified generator name matches a registered <identifier-generator/>
final IdentifierGeneratorDefinition generatorDef =
sourceDocument.getMetadataCollector().getIdentifierGenerator( definition.getName() );
sourceDocument.getMetadataCollector()
.getIdentifierGenerator( definition.getName() );
final Map<String,Object> configuration = new HashMap<>();
final String generatorStrategy;
if ( generatorDef != null ) {
generatorStrategy = generatorDef.getStrategy();
@ -863,20 +650,16 @@ public class GeneratorBinder {
generatorStrategy = definition.getStrategy();
}
// YUCK! but cannot think of a clean way to do this given the string-config based scheme
configuration.put( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER,
buildingContext.getObjectNameNormalizer() );
configuration.putAll( definition.getParameters() );
setGeneratorCreator( identifierValue, configuration, generatorStrategy, beanContainer( buildingContext ) );
setGeneratorCreator( identifierValue, configuration, generatorStrategy, context );
}
}
/**
* Obtain a {@link BeanContainer} to be used for instantiating generators.
*/
static BeanContainer beanContainer(MetadataBuildingContext buildingContext) {
private static BeanContainer beanContainer(MetadataBuildingContext buildingContext) {
final ServiceRegistry serviceRegistry = buildingContext.getBootstrapContext().getServiceRegistry();
return allowExtensionsInCdi( serviceRegistry )
? serviceRegistry.requireService( ManagedBeanRegistry.class ).getBeanContainer()
@ -891,12 +674,13 @@ public class GeneratorBinder {
SimpleValue identifierValue,
Map<String, Object> configuration,
String generatorStrategy,
BeanContainer beanContainer) {
MetadataBuildingContext context) {
if ( ASSIGNED_GENERATOR_NAME.equals( generatorStrategy )
|| org.hibernate.id.Assigned.class.getName().equals( generatorStrategy ) ) {
identifierValue.setCustomIdGeneratorCreator( ASSIGNED_IDENTIFIER_GENERATOR_CREATOR );
}
else {
final BeanContainer beanContainer = beanContainer( context );
identifierValue.setCustomIdGeneratorCreator( creationContext -> {
final Generator identifierGenerator =
instantiateGenerator( beanContainer, generatorClass( generatorStrategy, identifierValue ) );
@ -908,4 +692,82 @@ public class GeneratorBinder {
} );
}
}
/**
* Set up the id generator by considering all annotations of the identifier
* field, including {@linkplain IdGeneratorType id generator annotations},
* and {@link GeneratedValue}.
*/
static void createIdGeneratorsFromGeneratorAnnotations(
PropertyHolder propertyHolder,
PropertyData inferredData,
SimpleValue idValue,
Map<String, IdentifierGeneratorDefinition> classGenerators,
MetadataBuildingContext context) {
final SourceModelBuildingContext sourceModelContext =
context.getMetadataCollector().getSourceModelBuildingContext();
final MemberDetails idAttributeMember = inferredData.getAttributeMember();
final List<? extends Annotation> idGeneratorAnnotations =
idAttributeMember.getMetaAnnotated( IdGeneratorType.class, sourceModelContext );
final List<? extends Annotation> generatorAnnotations =
idAttributeMember.getMetaAnnotated( ValueGenerationType.class, sourceModelContext );
// Since these collections may contain Proxies created by common-annotations module we cannot reliably use simple remove/removeAll
// collection methods as those proxies do not implement hashcode/equals and even a simple `a.equals(a)` will return `false`.
// Instead, we will check the annotation types, since generator annotations should not be "repeatable" we should have only
// at most one annotation for a generator:
for ( Annotation id : idGeneratorAnnotations ) {
generatorAnnotations.removeIf( gen -> gen.annotationType().equals( id.annotationType() ) );
}
if ( idGeneratorAnnotations.size() + generatorAnnotations.size() > 1 ) {
throw new AnnotationException( String.format(
Locale.ROOT,
"Identifier attribute '%s' has too many generator annotations: %s",
getPath( propertyHolder, inferredData ),
CollectionHelper.combineUntyped( idGeneratorAnnotations, generatorAnnotations )
) );
}
if ( !idGeneratorAnnotations.isEmpty() ) {
idValue.setCustomIdGeneratorCreator( identifierGeneratorCreator(
idAttributeMember,
idGeneratorAnnotations.get(0),
idValue,
beanContainer( context )
) );
}
else if ( !generatorAnnotations.isEmpty() ) {
// idValue.setCustomGeneratorCreator( generatorCreator( idAttributeMember, generatorAnnotation ) );
throw new AnnotationException( String.format(
Locale.ROOT,
"Identifier attribute '%s' is annotated '%s' which is not an '@IdGeneratorType'",
getPath( propertyHolder, inferredData ),
generatorAnnotations.get(0).annotationType()
) );
}
else if ( idAttributeMember.hasDirectAnnotationUsage( GeneratedValue.class ) ) {
createIdGenerator( idValue, classGenerators, context, idAttributeMember );
}
}
/**
* Returns the value generation strategy for the given property, if any, by
* considering {@linkplain ValueGenerationType generator type annotations}.
*/
static GeneratorCreator createValueGeneratorFromAnnotations(
PropertyHolder holder, String propertyName,
MemberDetails property, MetadataBuildingContext context) {
final List<? extends Annotation> generatorAnnotations =
property.getMetaAnnotated( ValueGenerationType.class,
context.getMetadataCollector().getSourceModelBuildingContext() );
switch ( generatorAnnotations.size() ) {
case 0:
return null;
case 1:
return generatorCreator( property, generatorAnnotations.get(0), beanContainer( context ) );
default:
throw new AnnotationException( "Property '" + qualify( holder.getPath(), propertyName )
+ "' has too many generator annotations: " + generatorAnnotations );
}
}
}

View File

@ -0,0 +1,253 @@
/*
* 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.boot.model.internal;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.TableGenerator;
import jakarta.persistence.UniqueConstraint;
import org.hibernate.Internal;
import org.hibernate.boot.model.IdentifierGeneratorDefinition;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.config.spi.StandardConverters;
import org.hibernate.id.Configurable;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.OptimizableGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.enhanced.LegacyNamingStrategy;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.id.enhanced.SingleNamingStrategy;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.RootClass;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Table;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.Type;
import java.util.Map;
import java.util.Properties;
/**
* Responsible for setting up the parameters which are passed to
* {@link Configurable#configure(Type, Properties, ServiceRegistry)}
* when a {@link Configurable} generator is instantiated.
*
* @since 7.0
*
* @author Gavin King
*/
public class GeneratorParameters {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( GeneratorBinder.class );
/**
* Collect the parameters which should be passed to
* {@link Configurable#configure(Type, Properties, ServiceRegistry)}.
*/
public static Properties collectParameters(
SimpleValue identifierValue,
Dialect dialect,
RootClass rootClass,
Map<String, Object> configuration) {
final ConfigurationService configService =
identifierValue.getMetadata().getMetadataBuildingOptions().getServiceRegistry()
.requireService( ConfigurationService.class );
final Properties params = new Properties();
// default initial value and allocation size per-JPA defaults
params.setProperty( OptimizableGenerator.INITIAL_PARAM,
String.valueOf( OptimizableGenerator.DEFAULT_INITIAL_VALUE ) );
params.setProperty( OptimizableGenerator.INCREMENT_PARAM,
String.valueOf( defaultIncrement( configService ) ) );
//init the table here instead of earlier, so that we can get a quoted table name
//TODO: would it be better to simply pass the qualified table name, instead of
// splitting it up into schema/catalog/table names
final String tableName = identifierValue.getTable().getQuotedName( dialect );
params.setProperty( PersistentIdentifierGenerator.TABLE, tableName );
//pass the column name (a generated id almost always has a single column)
final Column column = (Column) identifierValue.getSelectables().get(0);
final String columnName = column.getQuotedName( dialect );
params.setProperty( PersistentIdentifierGenerator.PK, columnName );
//pass the entity-name, if not a collection-id
if ( rootClass != null ) {
params.setProperty( IdentifierGenerator.ENTITY_NAME, rootClass.getEntityName() );
params.setProperty( IdentifierGenerator.JPA_ENTITY_NAME, rootClass.getJpaEntityName() );
// The table name is not really a good default for subselect entities,
// so use the JPA entity name which is short
params.setProperty( OptimizableGenerator.IMPLICIT_NAME_BASE,
identifierValue.getTable().isSubselect()
? rootClass.getJpaEntityName()
: identifierValue.getTable().getName() );
params.setProperty( PersistentIdentifierGenerator.TABLES,
identityTablesString( dialect, rootClass ) );
}
else {
params.setProperty( PersistentIdentifierGenerator.TABLES, tableName );
params.setProperty( OptimizableGenerator.IMPLICIT_NAME_BASE, tableName );
}
params.put( IdentifierGenerator.CONTRIBUTOR_NAME,
identifierValue.getBuildingContext().getCurrentContributorName() );
final Map<String, Object> settings = configService.getSettings();
if ( settings.containsKey( AvailableSettings.PREFERRED_POOLED_OPTIMIZER ) ) {
params.put( AvailableSettings.PREFERRED_POOLED_OPTIMIZER,
settings.get( AvailableSettings.PREFERRED_POOLED_OPTIMIZER ) );
}
params.putAll( configuration );
return params;
}
private static String identityTablesString(Dialect dialect, RootClass rootClass) {
final StringBuilder tables = new StringBuilder();
for ( Table table : rootClass.getIdentityTables() ) {
tables.append( table.getQuotedName( dialect ) );
if ( !tables.isEmpty() ) {
tables.append( ", " );
}
}
return tables.toString();
}
private static int defaultIncrement(ConfigurationService configService) {
final String idNamingStrategy =
configService.getSetting( AvailableSettings.ID_DB_STRUCTURE_NAMING_STRATEGY,
StandardConverters.STRING, null );
if ( LegacyNamingStrategy.STRATEGY_NAME.equals( idNamingStrategy )
|| LegacyNamingStrategy.class.getName().equals( idNamingStrategy )
|| SingleNamingStrategy.STRATEGY_NAME.equals( idNamingStrategy )
|| SingleNamingStrategy.class.getName().equals( idNamingStrategy ) ) {
return 1;
}
else {
return OptimizableGenerator.DEFAULT_INCREMENT_SIZE;
}
}
@Internal
public static void interpretTableGenerator(
TableGenerator tableGeneratorAnnotation,
IdentifierGeneratorDefinition.Builder definitionBuilder) {
definitionBuilder.setName( tableGeneratorAnnotation.name() );
definitionBuilder.setStrategy( org.hibernate.id.enhanced.TableGenerator.class.getName() );
definitionBuilder.addParam( org.hibernate.id.enhanced.TableGenerator.CONFIG_PREFER_SEGMENT_PER_ENTITY, "true" );
final String catalog = tableGeneratorAnnotation.catalog();
if ( StringHelper.isNotEmpty( catalog ) ) {
definitionBuilder.addParam( PersistentIdentifierGenerator.CATALOG, catalog );
}
final String schema = tableGeneratorAnnotation.schema();
if ( StringHelper.isNotEmpty( schema ) ) {
definitionBuilder.addParam( PersistentIdentifierGenerator.SCHEMA, schema );
}
final String table = tableGeneratorAnnotation.table();
if ( StringHelper.isNotEmpty( table ) ) {
definitionBuilder.addParam( org.hibernate.id.enhanced.TableGenerator.TABLE_PARAM, table );
}
final String pkColumnName = tableGeneratorAnnotation.pkColumnName();
if ( StringHelper.isNotEmpty( pkColumnName ) ) {
definitionBuilder.addParam(
org.hibernate.id.enhanced.TableGenerator.SEGMENT_COLUMN_PARAM,
pkColumnName
);
}
final String pkColumnValue = tableGeneratorAnnotation.pkColumnValue();
if ( StringHelper.isNotEmpty( pkColumnValue ) ) {
definitionBuilder.addParam(
org.hibernate.id.enhanced.TableGenerator.SEGMENT_VALUE_PARAM,
pkColumnValue
);
}
final String valueColumnName = tableGeneratorAnnotation.valueColumnName();
if ( StringHelper.isNotEmpty( valueColumnName ) ) {
definitionBuilder.addParam(
org.hibernate.id.enhanced.TableGenerator.VALUE_COLUMN_PARAM,
valueColumnName
);
}
final String options = tableGeneratorAnnotation.options();
if ( StringHelper.isNotEmpty( options ) ) {
definitionBuilder.addParam(
PersistentIdentifierGenerator.OPTIONS,
options
);
}
definitionBuilder.addParam(
org.hibernate.id.enhanced.TableGenerator.INCREMENT_PARAM,
String.valueOf( tableGeneratorAnnotation.allocationSize() )
);
// See comment on HHH-4884 wrt initialValue. Basically initialValue is really the stated value + 1
definitionBuilder.addParam(
org.hibernate.id.enhanced.TableGenerator.INITIAL_PARAM,
String.valueOf( tableGeneratorAnnotation.initialValue() + 1 )
);
// TODO : implement unique-constraint support
final UniqueConstraint[] uniqueConstraints = tableGeneratorAnnotation.uniqueConstraints();
if ( CollectionHelper.isNotEmpty( uniqueConstraints ) ) {
LOG.ignoringTableGeneratorConstraints( tableGeneratorAnnotation.name() );
}
}
@Internal
public static void interpretSequenceGenerator(
SequenceGenerator sequenceGeneratorAnnotation,
IdentifierGeneratorDefinition.Builder definitionBuilder) {
definitionBuilder.setName( sequenceGeneratorAnnotation.name() );
definitionBuilder.setStrategy( SequenceStyleGenerator.class.getName() );
final String catalog = sequenceGeneratorAnnotation.catalog();
if ( StringHelper.isNotEmpty( catalog ) ) {
definitionBuilder.addParam( PersistentIdentifierGenerator.CATALOG, catalog );
}
final String schema = sequenceGeneratorAnnotation.schema();
if ( StringHelper.isNotEmpty( schema ) ) {
definitionBuilder.addParam( PersistentIdentifierGenerator.SCHEMA, schema );
}
final String sequenceName = sequenceGeneratorAnnotation.sequenceName();
if ( StringHelper.isNotEmpty( sequenceName ) ) {
definitionBuilder.addParam( SequenceStyleGenerator.SEQUENCE_PARAM, sequenceName );
}
definitionBuilder.addParam(
SequenceStyleGenerator.INCREMENT_PARAM,
String.valueOf( sequenceGeneratorAnnotation.allocationSize() )
);
definitionBuilder.addParam(
SequenceStyleGenerator.INITIAL_PARAM,
String.valueOf( sequenceGeneratorAnnotation.initialValue() )
);
final String options = sequenceGeneratorAnnotation.options();
if ( StringHelper.isNotEmpty( options ) ) {
definitionBuilder.addParam( PersistentIdentifierGenerator.OPTIONS, options );
}
}
}

View File

@ -0,0 +1,116 @@
/*
* 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.boot.model.internal;
import jakarta.persistence.GenerationType;
import org.hibernate.MappingException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.generator.Generator;
import org.hibernate.id.ForeignGenerator;
import org.hibernate.id.GUIDGenerator;
import org.hibernate.id.IdentityGenerator;
import org.hibernate.id.IncrementGenerator;
import org.hibernate.id.SelectGenerator;
import org.hibernate.id.UUIDGenerator;
import org.hibernate.id.UUIDHexGenerator;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.models.spi.TypeDetails;
import java.util.UUID;
/**
* Handles interpretation of old {@code hbm.xml}-style generator strategy names.
*
* @since 7.0
*
* @author Gavin King
*/
public class GeneratorStrategies {
/**
* Interpret a JPA {@link GenerationType} as an old-style generator strategy name.
*
* @param generationType the type specified by {@link jakarta.persistence.GeneratedValue#strategy}
* @param name the name specified by {@link jakarta.persistence.GeneratedValue#generator}
* @param type the Java type of the generated identifier
* @return a {@code hbml.xml}-equivalent string identifying the strategy
*/
public static String generatorStrategy(GenerationType generationType, String name, TypeDetails type) {
switch ( generationType ) {
case IDENTITY:
return "identity";
case SEQUENCE:
return SequenceStyleGenerator.class.getName();
case TABLE:
return org.hibernate.id.enhanced.TableGenerator.class.getName();
case UUID:
return UUIDGenerator.class.getName();
case AUTO:
if ( UUID.class.isAssignableFrom( type.determineRawClass().toJavaClass() ) ) {
return UUIDGenerator.class.getName();
}
else if ( "increment".equalsIgnoreCase( name ) ) {
// special case for @GeneratedValue(name="increment")
// for some reason we consider there to be an implicit
// generator named 'increment' (doesn't seem very useful)
return IncrementGenerator.class.getName();
}
else {
return SequenceStyleGenerator.class.getName();
}
default:
throw new IllegalArgumentException( "Unsupported generation type:" + generationType );
}
}
/**
* Interpret an "old" generator strategy name as a {@link Generator} class.
*/
public static Class<? extends Generator> generatorClass(String strategy, SimpleValue idValue) {
if ( "native".equals(strategy) ) {
strategy =
idValue.getMetadata().getDatabase().getDialect()
.getNativeIdentifierGeneratorStrategy();
}
switch (strategy) {
case "assigned":
return org.hibernate.id.Assigned.class;
case "enhanced-sequence":
case "sequence":
return SequenceStyleGenerator.class;
case "enhanced-table":
case "table":
return org.hibernate.id.enhanced.TableGenerator.class;
case "identity":
return IdentityGenerator.class;
case "increment":
return IncrementGenerator.class;
case "foreign":
return ForeignGenerator.class;
case "uuid":
case "uuid.hex":
return UUIDHexGenerator.class;
case "uuid2":
return UUIDGenerator.class;
case "select":
return SelectGenerator.class;
case "guid":
return GUIDGenerator.class;
}
final Class<? extends Generator> clazz =
idValue.getServiceRegistry().requireService( ClassLoaderService.class )
.classForName( strategy );
if ( !Generator.class.isAssignableFrom( clazz ) ) {
// in principle, this shouldn't happen, since @GenericGenerator
// constrains the type to subtypes of Generator
throw new MappingException( clazz.getName() + " does not implement 'Generator'" );
}
return clazz;
}
}

View File

@ -26,6 +26,7 @@ import org.hibernate.usertype.UserCollectionType;
import jakarta.persistence.Column;
import static org.hibernate.boot.model.internal.BinderHelper.isGlobalGeneratorNameGlobal;
import static org.hibernate.boot.model.internal.GeneratorBinder.makeIdGenerator;
/**
@ -131,7 +132,7 @@ public class IdBagBinder extends BagBinder {
generatorName = namedGenerator;
}
if ( buildingContext.getBootstrapContext().getJpaCompliance().isGlobalGeneratorScopeEnabled() ) {
if ( isGlobalGeneratorNameGlobal( buildingContext ) ) {
SecondPass secondPass = new IdGeneratorResolverSecondPass(
id,
property,

View File

@ -9,7 +9,6 @@ package org.hibernate.boot.model.internal;
import java.util.Map;
import org.hibernate.MappingException;
import org.hibernate.boot.model.IdentifierGeneratorDefinition;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.boot.spi.SecondPass;
import org.hibernate.mapping.PersistentClass;
@ -27,7 +26,7 @@ public class IdGeneratorResolverSecondPass implements SecondPass {
private final String generatorType;
private final String generatorName;
private final MetadataBuildingContext buildingContext;
private IdentifierGeneratorDefinition localIdentifierGeneratorDefinition;
// private IdentifierGeneratorDefinition localIdentifierGeneratorDefinition;
public IdGeneratorResolverSecondPass(
SimpleValue id,
@ -42,19 +41,33 @@ public class IdGeneratorResolverSecondPass implements SecondPass {
this.buildingContext = buildingContext;
}
public IdGeneratorResolverSecondPass(
SimpleValue id,
MemberDetails idAttributeMember,
String generatorType,
String generatorName,
MetadataBuildingContext buildingContext,
IdentifierGeneratorDefinition localIdentifierGeneratorDefinition) {
this( id, idAttributeMember, generatorType, generatorName, buildingContext );
this.localIdentifierGeneratorDefinition = localIdentifierGeneratorDefinition;
}
// public IdGeneratorResolverSecondPass(
// SimpleValue id,
// MemberDetails idAttributeMember,
// String generatorType,
// String generatorName,
// MetadataBuildingContext buildingContext,
// IdentifierGeneratorDefinition localIdentifierGeneratorDefinition) {
// this( id, idAttributeMember, generatorType, generatorName, buildingContext );
// this.localIdentifierGeneratorDefinition = localIdentifierGeneratorDefinition;
// }
@Override
public void doSecondPass(Map<String, PersistentClass> idGeneratorDefinitionMap) throws MappingException {
makeIdGenerator( id, idAttributeMember, generatorType, generatorName, buildingContext, localIdentifierGeneratorDefinition );
// makeIdGenerator( id, idAttributeMember, generatorType, generatorName, buildingContext, localIdentifierGeneratorDefinition );
makeIdGenerator( id, idAttributeMember, generatorType, generatorName, buildingContext, null );
}
// public static void makeIdGenerator(
// SimpleValue id,
// MemberDetails idAttributeMember,
// String generatorType,
// String generatorName,
// MetadataBuildingContext buildingContext,
// IdentifierGeneratorDefinition foreignKGeneratorDefinition) {
// makeIdGenerator( id, idAttributeMember, generatorType, generatorName, buildingContext,
// foreignKGeneratorDefinition != null
// ? Map.of( foreignKGeneratorDefinition.getName(), foreignKGeneratorDefinition )
// : null );
// }
}

View File

@ -9,7 +9,6 @@ package org.hibernate.boot.model.internal;
import java.lang.annotation.Annotation;
import java.util.EnumSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.hibernate.AnnotationException;
@ -18,7 +17,6 @@ import org.hibernate.MappingException;
import org.hibernate.annotations.Any;
import org.hibernate.annotations.AttributeBinderType;
import org.hibernate.annotations.CompositeType;
import org.hibernate.annotations.IdGeneratorType;
import org.hibernate.annotations.Immutable;
import org.hibernate.annotations.Index;
import org.hibernate.annotations.LazyGroup;
@ -26,7 +24,6 @@ import org.hibernate.annotations.ManyToAny;
import org.hibernate.annotations.NaturalId;
import org.hibernate.annotations.OptimisticLock;
import org.hibernate.annotations.Parent;
import org.hibernate.annotations.ValueGenerationType;
import org.hibernate.binder.AttributeBinder;
import org.hibernate.boot.model.IdentifierGeneratorDefinition;
import org.hibernate.boot.model.naming.Identifier;
@ -47,7 +44,6 @@ import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.GeneratorCreator;
import org.hibernate.mapping.Join;
import org.hibernate.mapping.KeyValue;
import org.hibernate.mapping.MappedSuperclass;
@ -90,17 +86,14 @@ import static org.hibernate.boot.model.internal.BinderHelper.getMappedSuperclass
import static org.hibernate.boot.model.internal.BinderHelper.getPath;
import static org.hibernate.boot.model.internal.BinderHelper.getPropertyOverriddenByMapperOrMapsId;
import static org.hibernate.boot.model.internal.BinderHelper.hasToOneAnnotation;
import static org.hibernate.boot.model.internal.BinderHelper.isCompositeId;
import static org.hibernate.boot.model.internal.ClassPropertyHolder.handleGenericComponentProperty;
import static org.hibernate.boot.model.internal.ClassPropertyHolder.prepareActualProperty;
import static org.hibernate.boot.model.internal.CollectionBinder.bindCollection;
import static org.hibernate.boot.model.internal.EmbeddableBinder.createCompositeBinder;
import static org.hibernate.boot.model.internal.EmbeddableBinder.createEmbeddable;
import static org.hibernate.boot.model.internal.EmbeddableBinder.isEmbedded;
import static org.hibernate.boot.model.internal.GeneratorBinder.beanContainer;
import static org.hibernate.boot.model.internal.GeneratorBinder.createIdGenerator;
import static org.hibernate.boot.model.internal.GeneratorBinder.generatorCreator;
import static org.hibernate.boot.model.internal.GeneratorBinder.identifierGeneratorCreator;
import static org.hibernate.boot.model.internal.GeneratorBinder.createIdGeneratorsFromGeneratorAnnotations;
import static org.hibernate.boot.model.internal.GeneratorBinder.createValueGeneratorFromAnnotations;
import static org.hibernate.boot.model.internal.TimeZoneStorageHelper.resolveTimeZoneStorageCompositeUserType;
import static org.hibernate.boot.model.internal.ToOneBinder.bindManyToOne;
import static org.hibernate.boot.model.internal.ToOneBinder.bindOneToOne;
@ -449,35 +442,12 @@ public class PropertyBinder {
}
private void handleValueGeneration(Property property) {
if ( this.memberDetails != null ) {
property.setValueGeneratorCreator( getValueGenerationFromAnnotations( this.memberDetails ) );
if ( memberDetails != null ) {
property.setValueGeneratorCreator(
createValueGeneratorFromAnnotations( holder, name, memberDetails, buildingContext ) );
}
}
/**
* Returns the value generation strategy for the given property, if any.
*/
private GeneratorCreator getValueGenerationFromAnnotations(MemberDetails property) {
GeneratorCreator creator = null;
final List<? extends Annotation> metaAnnotatedTargets = property.getMetaAnnotated(
ValueGenerationType.class,
getSourceModelContext()
);
for ( Annotation metaAnnotatedTarget : metaAnnotatedTargets ) {
final GeneratorCreator candidate = generatorCreator( property, metaAnnotatedTarget, beanContainer( buildingContext ) );
if ( candidate != null ) {
if ( creator != null ) {
throw new AnnotationException( "Property '" + qualify( holder.getPath(), name )
+ "' has multiple '@ValueGenerationType' annotations" );
}
else {
creator = candidate;
}
}
}
return creator;
}
private void handleLob(Property property) {
if ( this.memberDetails != null ) {
// HHH-4635 -- needed for dialect-specific property ordering
@ -1181,12 +1151,15 @@ public class PropertyBinder {
}
else if ( propertyBinder.isId() ) {
//components and regular basic types create SimpleValue objects
processId(
if ( isIdentifierMapper ) {
throw new AnnotationException( "Property '"+ getPath( propertyHolder, inferredData )
+ "' belongs to an '@IdClass' and may not be annotated '@Id' or '@EmbeddedId'" );
}
createIdGeneratorsFromGeneratorAnnotations(
propertyHolder,
inferredData,
(SimpleValue) propertyBinder.getValue(),
classGenerators,
isIdentifierMapper,
context
);
}
@ -1457,71 +1430,4 @@ public class PropertyBinder {
return null;
}
private static void processId(
PropertyHolder propertyHolder,
PropertyData inferredData,
SimpleValue idValue,
Map<String, IdentifierGeneratorDefinition> classGenerators,
boolean isIdentifierMapper,
MetadataBuildingContext context) {
if ( isIdentifierMapper ) {
throw new AnnotationException( "Property '"+ getPath( propertyHolder, inferredData )
+ "' belongs to an '@IdClass' and may not be annotated '@Id' or '@EmbeddedId'" );
}
final SourceModelBuildingContext sourceModelContext = context.getMetadataCollector().getSourceModelBuildingContext();
final MemberDetails idAttributeMember = inferredData.getAttributeMember();
final List<? extends Annotation> idGeneratorAnnotations = idAttributeMember.getMetaAnnotated( IdGeneratorType.class, sourceModelContext );
final List<? extends Annotation> generatorAnnotations = idAttributeMember.getMetaAnnotated( ValueGenerationType.class, sourceModelContext );
removeIdGenerators( generatorAnnotations, idGeneratorAnnotations );
if ( idGeneratorAnnotations.size() + generatorAnnotations.size() > 1 ) {
throw new AnnotationException( String.format(
Locale.ROOT,
"Property `%s` has too many generator annotations : %s",
getPath( propertyHolder, inferredData ),
CollectionHelper.combineUntyped( idGeneratorAnnotations, generatorAnnotations )
) );
}
if ( !idGeneratorAnnotations.isEmpty() ) {
idValue.setCustomIdGeneratorCreator( identifierGeneratorCreator(
idAttributeMember,
idGeneratorAnnotations.get(0),
idValue,
beanContainer( context )
) );
}
else if ( !generatorAnnotations.isEmpty() ) {
// idValue.setCustomGeneratorCreator( generatorCreator( idAttributeMember, generatorAnnotation ) );
throw new AnnotationException( String.format(
Locale.ROOT,
"Property '%s' is annotated `%s` which is not an `@IdGeneratorType`",
getPath( propertyHolder, inferredData ),
generatorAnnotations.get(0).annotationType()
) );
}
else {
final ClassDetails entityClass = inferredData.getClassOrElementType().determineRawClass();
createIdGenerator( idValue, classGenerators, context, entityClass, idAttributeMember );
if ( LOG.isTraceEnabled() ) {
LOG.tracev(
"Bind {0} on {1}",
isCompositeId( entityClass, idAttributeMember ) ? "@EmbeddedId" : "@Id",
inferredData.getPropertyName()
);
}
}
}
// Since these collections may contain Proxies created by common-annotations module we cannot reliably use simple remove/removeAll
// collection methods as those proxies do not implement hashcode/equals and even a simple `a.equals(a)` will return `false`.
// Instead, we will check the annotation types, since generator annotations should not be "repeatable" we should have only
// at most one annotation for a generator:
private static void removeIdGenerators(
List<? extends Annotation> generatorAnnotations,
List<? extends Annotation> idGeneratorAnnotations) {
for ( Annotation id : idGeneratorAnnotations ) {
generatorAnnotations.removeIf( gen -> gen.annotationType().equals( id.annotationType() ) );
}
}
}

View File

@ -194,7 +194,7 @@ public class ToOneBinder {
// This is a @OneToOne mapped to a physical o.h.mapping.ManyToOne
value.markAsLogicalOneToOne();
}
value.setReferencedEntityName( getReferenceEntityName( inferredData, targetEntity, context ) );
value.setReferencedEntityName( getReferenceEntityName( inferredData, targetEntity ) );
final MemberDetails property = inferredData.getAttributeMember();
defineFetchingStrategy( value, property, inferredData, propertyHolder );
//value.setFetchMode( fetchMode );
@ -231,7 +231,7 @@ public class ToOneBinder {
value,
joinColumns,
unique,
isTargetAnnotatedEntity( targetEntity, property, context ),
isTargetAnnotatedEntity( targetEntity, property ),
propertyHolder.getPersistentClass(),
fullPath,
context
@ -257,8 +257,8 @@ public class ToOneBinder {
);
}
static boolean isTargetAnnotatedEntity(ClassDetails targetEntity, MemberDetails property, MetadataBuildingContext context) {
final ClassDetails target = isDefault( targetEntity, context ) ? property.getType().determineRawClass() : targetEntity;
static boolean isTargetAnnotatedEntity(ClassDetails targetEntity, MemberDetails property) {
final ClassDetails target = isDefault( targetEntity ) ? property.getType().determineRawClass() : targetEntity;
return target.hasDirectAnnotationUsage( Entity.class );
}
@ -535,8 +535,8 @@ public class ToOneBinder {
propertyHolder.getEntityName(),
propertyHolder,
inferredData,
getReferenceEntityName( inferredData, targetEntity, context ),
isTargetAnnotatedEntity( targetEntity, annotatedProperty, context ),
getReferenceEntityName( inferredData, targetEntity ),
isTargetAnnotatedEntity( targetEntity, annotatedProperty ),
notFoundAction,
cascadeOnDelete,
optional,
@ -653,14 +653,14 @@ public class ToOneBinder {
}
}
public static String getReferenceEntityName(PropertyData propertyData, ClassDetails targetEntity, MetadataBuildingContext context) {
return isDefault( targetEntity, context )
public static String getReferenceEntityName(PropertyData propertyData, ClassDetails targetEntity) {
return isDefault( targetEntity )
? propertyData.getClassOrElementName()
: targetEntity.getName();
}
public static String getReferenceEntityName(PropertyData propertyData, MetadataBuildingContext context) {
return getReferenceEntityName( propertyData, getTargetEntity( propertyData, context ), context );
return getReferenceEntityName( propertyData, getTargetEntity( propertyData, context ) );
}
public static ClassDetails getTargetEntity(PropertyData propertyData, MetadataBuildingContext context) {

View File

@ -24,7 +24,6 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.generator.values.internal.GeneratedValuesHelper;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.SqlTypedMapping;
import org.hibernate.metamodel.model.domain.NavigableRole;
@ -34,6 +33,7 @@ import org.hibernate.type.Type;
import org.hibernate.type.descriptor.WrapperOptions;
import static org.hibernate.engine.internal.ForeignKeys.getEntityIdentifierIfNotUnsaved;
import static org.hibernate.internal.util.StringHelper.unquote;
import static org.hibernate.spi.NavigablePath.IDENTIFIER_MAPPER_PROPERTY;
/**
@ -124,7 +124,7 @@ public final class IdentifierGeneratorHelper {
private static boolean equal(String keyColumnName, String alias, Dialect dialect) {
return alias.equalsIgnoreCase( keyColumnName )
|| alias.equalsIgnoreCase( StringHelper.unquote( keyColumnName, dialect ) );
|| alias.equalsIgnoreCase( unquote( keyColumnName, dialect ) );
}
public static IntegralDataTypeHolder getIntegralDataTypeHolder(Class<?> integralType) {

View File

@ -15,7 +15,7 @@ import java.util.Properties;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.boot.model.naming.ObjectNameNormalizer;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.relational.QualifiedTableName;
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
import org.hibernate.dialect.Dialect;
@ -29,10 +29,10 @@ import org.hibernate.type.Type;
import static org.hibernate.id.IdentifierGeneratorHelper.getIntegralDataTypeHolder;
import static org.hibernate.id.PersistentIdentifierGenerator.CATALOG;
import static org.hibernate.id.PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER;
import static org.hibernate.id.PersistentIdentifierGenerator.PK;
import static org.hibernate.id.PersistentIdentifierGenerator.SCHEMA;
import static org.hibernate.internal.util.StringHelper.split;
import static org.hibernate.internal.util.config.ConfigurationHelper.getString;
/**
* An {@link IdentifierGenerator} that returns a {@code long}, constructed by counting
@ -89,18 +89,17 @@ public class IncrementGenerator implements IdentifierGenerator {
returnClass = type.getReturnedClass();
final JdbcEnvironment jdbcEnvironment = serviceRegistry.requireService( JdbcEnvironment.class );
final ObjectNameNormalizer normalizer = (ObjectNameNormalizer) parameters.get( IDENTIFIER_NORMALIZER );
final IdentifierHelper identifierHelper = jdbcEnvironment.getIdentifierHelper();
column = parameters.getProperty( COLUMN );
if ( column == null ) {
column = parameters.getProperty( PK );
}
column = normalizer.normalizeIdentifierQuoting( column ).render( jdbcEnvironment.getDialect() );
column = identifierHelper.normalizeQuoting( identifierHelper.toIdentifier( column ) )
.render( jdbcEnvironment.getDialect() );
IdentifierHelper identifierHelper = jdbcEnvironment.getIdentifierHelper();
final String schema = normalizer.toDatabaseIdentifierText( parameters.getProperty( SCHEMA ) );
final String catalog = normalizer.toDatabaseIdentifierText( parameters.getProperty( CATALOG ) );
final Identifier catalog = identifierHelper.toIdentifier( getString( CATALOG, parameters ) );
final Identifier schema = identifierHelper.toIdentifier( getString( SCHEMA, parameters ) );
String tableList = parameters.getProperty( TABLES );
if ( tableList == null ) {
@ -108,8 +107,7 @@ public class IncrementGenerator implements IdentifierGenerator {
}
physicalTableNames = new ArrayList<>();
for ( String tableName : split( ", ", tableList ) ) {
physicalTableNames.add( new QualifiedTableName( identifierHelper.toIdentifier( catalog ),
identifierHelper.toIdentifier( schema ), identifierHelper.toIdentifier( tableName ) ) );
physicalTableNames.add( new QualifiedTableName( catalog, schema, identifierHelper.toIdentifier( tableName ) ) );
}
}

View File

@ -53,7 +53,10 @@ public interface PersistentIdentifierGenerator extends OptimizableGenerator {
/**
* The key under which to find the {@link org.hibernate.boot.model.naming.ObjectNameNormalizer} in the config param map.
*
* @deprecated no longer set, use {@link org.hibernate.engine.jdbc.env.spi.JdbcEnvironment#getIdentifierHelper}
*/
@Deprecated(since = "7.0", forRemoval = true)
String IDENTIFIER_NORMALIZER = "identifier_normalizer";
/**

View File

@ -6,7 +6,6 @@
*/
package org.hibernate.internal.util.collections;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

View File

@ -18,7 +18,6 @@ import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.type.StandardBasicTypes;
@ -63,10 +62,6 @@ public class SequenceStyleGeneratorBehavesLikeSequeceHiloGeneratorWitZeroIncreme
properties.setProperty( SequenceStyleGenerator.SEQUENCE_PARAM, TEST_SEQUENCE );
properties.setProperty( SequenceStyleGenerator.OPT_PARAM, "legacy-hilo" );
properties.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "0" ); // JPA allocationSize of 1
properties.put(
PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER,
buildingContext.getObjectNameNormalizer()
);
generator.configure(
buildingContext.getBootstrapContext()
.getTypeConfiguration()

View File

@ -11,7 +11,6 @@ import java.util.Properties;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.boot.model.relational.internal.SqlStringGenerationContextImpl;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Environment;
@ -96,10 +95,6 @@ public class SequenceStyleConfigUnitTest {
private Properties buildGeneratorPropertiesBase(MetadataBuildingContext buildingContext) {
Properties props = new Properties();
props.put(
PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER,
buildingContext.getObjectNameNormalizer()
);
props.put(
PersistentIdentifierGenerator.IMPLICIT_NAME_BASE,
"ID"