HHH-18139 clean up / reorg of generator binding related code
Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
parent
58f555ab39
commit
1d7ed0e84d
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
} );
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1614,7 +1614,7 @@ public abstract class CollectionBinder {
|
|||
}
|
||||
|
||||
TypeDetails getElementType() {
|
||||
if ( isDefault( targetEntity, buildingContext ) ) {
|
||||
if ( isDefault( targetEntity ) ) {
|
||||
if ( collectionElementType != null ) {
|
||||
return collectionElementType;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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 );
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -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() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue