HHH-17878 `Configurable` generators and `@IdGeneratorType`

This commit is contained in:
Marco Belladelli 2024-03-22 15:56:12 +01:00 committed by Christian Beikov
parent be9466ede4
commit ddb2324736
3 changed files with 31 additions and 5 deletions

View File

@ -34,6 +34,7 @@ import org.hibernate.generator.BeforeExecutionGenerator;
import org.hibernate.generator.Generator; import org.hibernate.generator.Generator;
import org.hibernate.generator.GeneratorCreationContext; import org.hibernate.generator.GeneratorCreationContext;
import org.hibernate.generator.OnExecutionGenerator; import org.hibernate.generator.OnExecutionGenerator;
import org.hibernate.id.Configurable;
import org.hibernate.id.IdentifierGenerator; import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.PersistentIdentifierGenerator; import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.factory.spi.CustomIdGeneratorCreationContext; import org.hibernate.id.factory.spi.CustomIdGeneratorCreationContext;
@ -42,6 +43,7 @@ import org.hibernate.mapping.GeneratorCreator;
import org.hibernate.mapping.IdentifierGeneratorCreator; import org.hibernate.mapping.IdentifierGeneratorCreator;
import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Table; import org.hibernate.mapping.Table;
import org.hibernate.mapping.Value;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
@ -55,6 +57,7 @@ import jakarta.persistence.Version;
import static org.hibernate.boot.model.internal.BinderHelper.isCompositeId; import static org.hibernate.boot.model.internal.BinderHelper.isCompositeId;
import static org.hibernate.boot.model.internal.BinderHelper.isGlobalGeneratorNameGlobal; import static org.hibernate.boot.model.internal.BinderHelper.isGlobalGeneratorNameGlobal;
import static org.hibernate.id.factory.internal.IdentifierGeneratorUtil.collectParameters;
import static org.hibernate.mapping.SimpleValue.DEFAULT_ID_GEN_STRATEGY; import static org.hibernate.mapping.SimpleValue.DEFAULT_ID_GEN_STRATEGY;
public class GeneratorBinder { public class GeneratorBinder {
@ -391,6 +394,7 @@ public class GeneratorBinder {
generatorClass generatorClass
); );
callInitialize( annotation, member, creationContext, generator ); callInitialize( annotation, member, creationContext, generator );
callConfigure( creationContext, generator );
checkIdGeneratorTiming( annotationType, generator ); checkIdGeneratorTiming( annotationType, generator );
return generator; return generator;
}; };
@ -433,7 +437,7 @@ public class GeneratorBinder {
Member member, Member member,
GeneratorCreationContext creationContext, GeneratorCreationContext creationContext,
Generator generator) { Generator generator) {
if ( generator instanceof AnnotationBasedGenerator) { if ( generator instanceof AnnotationBasedGenerator ) {
// This will cause a CCE in case the generation type doesn't match the annotation type; As this would be // This will cause a CCE in case the generation type doesn't match the annotation type; As this would be
// a programming error of the generation type developer and thus should show up during testing, we don't // a programming error of the generation type developer and thus should show up during testing, we don't
// check this explicitly; If required, this could be done e.g. using ClassMate // check this explicitly; If required, this could be done e.g. using ClassMate
@ -458,6 +462,19 @@ public class GeneratorBinder {
} }
} }
private static void callConfigure(GeneratorCreationContext creationContext, Generator generator) {
if ( generator instanceof Configurable ) {
final Value value = creationContext.getProperty().getValue();
( (Configurable) generator ).configure( value.getType(), collectParameters(
(SimpleValue) value,
creationContext.getDatabase().getDialect(),
creationContext.getDefaultCatalog(),
creationContext.getDefaultSchema(),
creationContext.getPersistentClass().getRootClass()
), creationContext.getServiceRegistry() );
}
}
private static void checkIdGeneratorTiming(Class<? extends Annotation> annotationType, Generator generator) { private static void checkIdGeneratorTiming(Class<? extends Annotation> annotationType, Generator generator) {
if ( !generator.generatesOnInsert() ) { if ( !generator.generatesOnInsert() ) {
throw new MappingException( "Annotation '" + annotationType throw new MappingException( "Annotation '" + annotationType

View File

@ -41,8 +41,12 @@ public class IdentifierGeneratorUtil {
); );
} }
static Properties collectParameters( public static Properties collectParameters(
SimpleValue simpleValue, Dialect dialect, String defaultCatalog, String defaultSchema, RootClass rootClass) { SimpleValue simpleValue,
Dialect dialect,
String defaultCatalog,
String defaultSchema,
RootClass rootClass) {
final ConfigurationService configService = final ConfigurationService configService =
simpleValue.getMetadata().getMetadataBuildingOptions().getServiceRegistry() simpleValue.getMetadata().getMetadataBuildingOptions().getServiceRegistry()
.requireService( ConfigurationService.class ); .requireService( ConfigurationService.class );

View File

@ -193,12 +193,11 @@ public class SequenceOrAssignedGeneratorTest {
} }
@Entity( name = "MyEntity" ) @Entity( name = "MyEntity" )
@GenericGenerator( type = SequenceOrAssignedGenerator.class, name = MyEntity.SEQUENCE )
public static class MyEntity { public static class MyEntity {
protected static final String SEQUENCE = "SEQ_MyEntity"; protected static final String SEQUENCE = "SEQ_MyEntity";
@Id @Id
@GeneratedValue( generator = SEQUENCE ) @SequenceOrAssigned
private Long id; private Long id;
private String name; private String name;
@ -254,6 +253,12 @@ public class SequenceOrAssignedGeneratorTest {
} }
} }
@IdGeneratorType( SequenceOrAssignedGenerator.class )
@Target( { METHOD, FIELD } )
@Retention( RUNTIME )
public @interface SequenceOrAssigned {
}
public static class SequenceOrAssignedGenerator extends SequenceStyleGenerator { public static class SequenceOrAssignedGenerator extends SequenceStyleGenerator {
@Override @Override
public Object generate(SharedSessionContractImplementor session, Object owner) throws HibernateException { public Object generate(SharedSessionContractImplementor session, Object owner) throws HibernateException {