Skip to content

Commit

Permalink
finish the job of fully-unifying value generators with id generators
Browse files Browse the repository at this point in the history
by letting value generators implement Configurable and ExportableProducer
  • Loading branch information
gavinking committed Dec 23, 2024
1 parent d7a49e3 commit 35b47c4
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.hibernate.boot.spi.InFlightMetadataCollector;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.boot.spi.PropertyData;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.generator.AnnotationBasedGenerator;
import org.hibernate.generator.Assigned;
import org.hibernate.generator.BeforeExecutionGenerator;
Expand All @@ -46,6 +47,7 @@
import org.hibernate.mapping.KeyValue;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Value;
import org.hibernate.models.spi.AnnotationTarget;
import org.hibernate.models.spi.MemberDetails;
import org.hibernate.models.spi.SourceModelBuildingContext;
Expand Down Expand Up @@ -344,17 +346,11 @@ private static void checkGeneratorClass(Class<? extends Generator> generatorClas
}

private static void checkGeneratorInterfaces(Class<? extends Generator> generatorClass) {
// we don't yet support the additional "fancy" operations of
// IdentifierGenerator with regular generators, though this
// would be extremely easy to add if anyone asks for it
// A regular value generator should not implement legacy IdentifierGenerator
if ( IdentifierGenerator.class.isAssignableFrom( generatorClass ) ) {
throw new AnnotationException("Generator class '" + generatorClass.getName()
+ "' implements 'IdentifierGenerator' and may not be used with '@ValueGenerationType'");
}
if ( ExportableProducer.class.isAssignableFrom( generatorClass ) ) {
throw new AnnotationException("Generator class '" + generatorClass.getName()
+ "' implements 'ExportableProducer' and may not be used with '@ValueGenerationType'");
}
}

/**
Expand All @@ -363,6 +359,7 @@ private static void checkGeneratorInterfaces(Class<? extends Generator> generato
*/
private static GeneratorCreator generatorCreator(
MemberDetails memberDetails,
Value value,
Annotation annotation,
BeanContainer beanContainer) {
final Class<? extends Annotation> annotationType = annotation.annotationType();
Expand All @@ -372,21 +369,42 @@ private static GeneratorCreator generatorCreator(
checkGeneratorClass( generatorClass );
checkGeneratorInterfaces( generatorClass );
return creationContext -> {
final Generator generator = instantiateGenerator(
annotation,
beanContainer,
creationContext,
generatorClass,
memberDetails,
annotationType
);
callInitialize( annotation, memberDetails, creationContext, generator );
//TODO: callConfigure( creationContext, generator, emptyMap(), identifierValue );
final Generator generator =
instantiateAndInitializeGenerator(
value,
annotation,
beanContainer,
creationContext,
generatorClass,
memberDetails,
annotationType
);
checkVersionGenerationAlways( memberDetails, generator );
return generator;
};
}

private static Generator instantiateAndInitializeGenerator(
Value value,
Annotation annotation,
BeanContainer beanContainer,
GeneratorCreationContext creationContext,
Class<? extends Generator> generatorClass,
MemberDetails memberDetails,
Class<? extends Annotation> annotationType) {
final Generator generator = instantiateGenerator(
annotation,
beanContainer,
creationContext,
generatorClass,
memberDetails,
annotationType
);
callInitialize( annotation, memberDetails, creationContext, generator );
callConfigure( creationContext, generator, emptyMap(), value );
return generator;
}

/**
* Return a {@link GeneratorCreator} for an id attribute annotated
* with an {@linkplain IdGeneratorType id generator annotation}.
Expand All @@ -403,16 +421,15 @@ private static GeneratorCreator identifierGeneratorCreator(
checkGeneratorClass( generatorClass );
return creationContext -> {
final Generator generator =
instantiateGenerator(
instantiateAndInitializeGenerator(
identifierValue,
annotation,
beanContainer,
creationContext,
generatorClass,
idAttributeMember,
annotationType
);
callInitialize( annotation, idAttributeMember, creationContext, generator );
callConfigure( creationContext, generator, emptyMap(), identifierValue );
checkIdGeneratorTiming( annotationType, generator );
return generator;
};
Expand Down Expand Up @@ -610,13 +627,14 @@ public static void callConfigure(
GeneratorCreationContext creationContext,
Generator generator,
Map<String, Object> configuration,
SimpleValue identifierValue) {
Value value) {
if ( generator instanceof Configurable configurable ) {
final Properties parameters = collectParameters(
identifierValue,
value,
creationContext.getDatabase().getDialect(),
creationContext.getRootClass(),
configuration
configuration,
creationContext.getServiceRegistry().requireService( ConfigurationService.class )
);
configurable.configure( creationContext, parameters );
}
Expand Down Expand Up @@ -838,13 +856,13 @@ else if ( idAttributeMember.hasDirectAnnotationUsage( GeneratedValue.class ) ) {
*/
static GeneratorCreator createValueGeneratorFromAnnotations(
PropertyHolder holder, String propertyName,
MemberDetails property, MetadataBuildingContext context) {
Value value, MemberDetails property, MetadataBuildingContext context) {
final List<? extends Annotation> generatorAnnotations =
property.getMetaAnnotated( ValueGenerationType.class,
context.getMetadataCollector().getSourceModelBuildingContext() );
return switch ( generatorAnnotations.size() ) {
case 0 -> null;
case 1 -> generatorCreator( property, generatorAnnotations.get(0), beanContainer( context ) );
case 1 -> generatorCreator( property, value, generatorAnnotations.get(0), beanContainer( context ) );
default -> throw new AnnotationException( "Property '" + qualify( holder.getPath(), propertyName )
+ "' has too many generator annotations: " + generatorAnnotations );
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.RootClass;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Table;

import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.TableGenerator;
import jakarta.persistence.UniqueConstraint;
import org.hibernate.mapping.Value;

import static org.hibernate.cfg.MappingSettings.ID_DB_STRUCTURE_NAMING_STRATEGY;
import static org.hibernate.id.IdentifierGenerator.CONTRIBUTOR_NAME;
Expand Down Expand Up @@ -66,40 +66,25 @@ public class GeneratorParameters {
* {@link Configurable#configure(GeneratorCreationContext, Properties)}.
*/
public static Properties collectParameters(
SimpleValue identifierValue,
Dialect dialect,
RootClass rootClass) {
final Properties params = new Properties();
collectParameters( identifierValue, dialect, rootClass, params::put );
return params;
}

/**
* Collect the parameters which should be passed to
* {@link Configurable#configure(GeneratorCreationContext, Properties)}.
*/
public static Properties collectParameters(
SimpleValue identifierValue,
Value identifierValue,
Dialect dialect,
RootClass rootClass,
Map<String, Object> configuration) {
final Properties params = collectParameters( identifierValue, dialect, rootClass );
Map<String, Object> configuration,
ConfigurationService configService) {
final Properties params = new Properties();
collectParameters( identifierValue, dialect, rootClass, params::put, configService );
if ( configuration != null ) {
params.putAll( configuration );
}
return params;
}

public static void collectParameters(
SimpleValue identifierValue,
Value identifierValue,
Dialect dialect,
RootClass rootClass,
BiConsumer<String,String> parameterCollector) {

final ConfigurationService configService =
identifierValue.getMetadata().getMetadataBuildingOptions()
.getServiceRegistry().requireService( ConfigurationService.class );

BiConsumer<String, String> parameterCollector,
ConfigurationService configService) {
// default initial value and allocation size per-JPA defaults
parameterCollector.accept( INITIAL_PARAM, String.valueOf( DEFAULT_INITIAL_VALUE ) );
parameterCollector.accept( INCREMENT_PARAM, String.valueOf( defaultIncrement( configService ) ) );
Expand All @@ -124,7 +109,7 @@ public static int fallbackAllocationSize(Annotation generatorAnnotation, Metadat
}

static void collectBaselineProperties(
SimpleValue identifierValue,
Value identifierValue,
Dialect dialect,
RootClass rootClass,
BiConsumer<String,String> parameterCollector,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ public Property makeProperty() {
private void handleValueGeneration(Property property) {
if ( memberDetails != null ) {
property.setValueGeneratorCreator(
createValueGeneratorFromAnnotations( holder, name, memberDetails, buildingContext ) );
createValueGeneratorFromAnnotations( holder, name, value, memberDetails, buildingContext ) );
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

import jakarta.persistence.GenerationType;
import jakarta.persistence.SequenceGenerator;
import org.hibernate.boot.model.internal.GeneratorParameters;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.boot.model.relational.ExportableProducer;
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.generator.AnnotationBasedGenerator;
import org.hibernate.generator.BeforeExecutionGenerator;
Expand All @@ -22,14 +22,14 @@
import org.hibernate.id.enhanced.TableGenerator;
import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
import org.hibernate.id.uuid.UuidGenerator;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.persister.entity.EntityPersister;

import java.lang.reflect.Member;
import java.util.EnumSet;
import java.util.Map;
import java.util.Properties;

import static org.hibernate.boot.model.internal.GeneratorParameters.collectParameters;
import static org.hibernate.id.IdentifierGenerator.GENERATOR_NAME;
import static org.hibernate.id.OptimizableGenerator.INCREMENT_PARAM;

Expand Down Expand Up @@ -169,11 +169,12 @@ private void applyProperties(
private static void applyCommonConfiguration(
Map<String, Object> mapRef,
GeneratorCreationContext context) {
GeneratorParameters.collectParameters(
(SimpleValue) context.getProperty().getValue(),
collectParameters(
context.getProperty().getValue(),
context.getDatabase().getDialect(),
context.getRootClass(),
mapRef::put
mapRef::put,
context.getServiceRegistry().requireService( ConfigurationService.class )
);
mapRef.put( INCREMENT_PARAM, 1 );
}
Expand Down

0 comments on commit 35b47c4

Please sign in to comment.