From 2f335cd786b1cd84e7f299f4e5ecd882ec00fb0c Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Mon, 23 Sep 2024 13:44:48 -0500 Subject: [PATCH] HHH-18377 - Support for uuid v6 and v7 generated ids --- .../hibernate/annotations/UuidGenerator.java | 2 + .../org/hibernate/id/uuid/UuidGenerator.java | 118 ++++++++---------- 2 files changed, 55 insertions(+), 65 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/UuidGenerator.java b/hibernate-core/src/main/java/org/hibernate/annotations/UuidGenerator.java index 38fabec3a2..f1d6ebd3e8 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/UuidGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/UuidGenerator.java @@ -60,12 +60,14 @@ public @interface UuidGenerator { * version 6. * @see UuidVersion6Strategy */ + @Incubating VERSION_6, /** * Use a time-based generation strategy consistent with RFC 4122 * version 7. * @see UuidVersion7Strategy */ + @Incubating VERSION_7 } diff --git a/hibernate-core/src/main/java/org/hibernate/id/uuid/UuidGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/uuid/UuidGenerator.java index 92b4465b7b..139db76ecd 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/uuid/UuidGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/id/uuid/UuidGenerator.java @@ -56,25 +56,68 @@ public class UuidGenerator implements BeforeExecutionGenerator { public UuidGenerator( org.hibernate.annotations.UuidGenerator config, MemberDetails memberDetails) { - generator = determineValueGenerator( config, memberDetails ); + generator = determineValueGenerator( config, memberDetails.getDeclaringType().getName(), memberDetails.getName() ); final Class memberType = memberDetails.getType().determineRawClass().toJavaClass(); valueTransformer = determineProperTransformer( memberType ); } + @Internal + public UuidGenerator( + org.hibernate.annotations.UuidGenerator config, + Member idMember) { + generator = determineValueGenerator( config, idMember.getDeclaringClass().getName(), idMember.getName() ); + + final Class propertyType = getPropertyType( idMember ); + this.valueTransformer = determineProperTransformer( propertyType ); + } + + public UuidGenerator( + org.hibernate.annotations.UuidGenerator config, + Member member, + GeneratorCreationContext creationContext) { + this( config, member ); + } + + /** + * @return {@link EventTypeSets#INSERT_ONLY} + */ + @Override + public EnumSet getEventTypes() { + return INSERT_ONLY; + } + + @Override + public Object generate(SharedSessionContractImplementor session, Object owner, Object currentValue, EventType eventType) { + return valueTransformer.transform( generator.generateUuid( session ) ); + } + + @Internal + public UuidValueGenerator getValueGenerator() { + return generator; + } + + @Internal + public ValueTransformer getValueTransformer() { + return valueTransformer; + } + private static UuidValueGenerator determineValueGenerator( org.hibernate.annotations.UuidGenerator config, - MemberDetails memberDetails) { + String memberDeclaringClassName, + String memberName) { if ( config != null ) { + // there is an annotation if ( config.algorithm() != UuidValueGenerator.class ) { + // the annotation specified a custom algorithm if ( config.style() != AUTO ) { throw new MappingException( String.format( Locale.ROOT, "Style [%s] should not be specified with custom UUID value generator : %s.%s", config.style().name(), - memberDetails.getDeclaringType().getName(), - memberDetails.getName() + memberDeclaringClassName, + memberName ) ); } @@ -83,46 +126,21 @@ public class UuidGenerator implements BeforeExecutionGenerator { if ( config.style() == TIME ) { return new CustomVersionOneStrategy(); } - else if ( config.style() == VERSION_6 ) { + if ( config.style() == VERSION_6 ) { return UuidVersion6Strategy.INSTANCE; } - else if ( config.style() == VERSION_7 ) { + if ( config.style() == VERSION_7 ) { return UuidVersion7Strategy.INSTANCE; } + // NOTE : AUTO falls through } + // Either - + // 1. there is no annotation + // 2. the annotation specified AUTO (with no custom algorithm) return StandardRandomStrategy.INSTANCE; } - @Internal - public UuidGenerator( - org.hibernate.annotations.UuidGenerator config, - Member idMember) { - if ( config.algorithm() != UuidValueGenerator.class ) { - if ( config.style() != AUTO ) { - throw new MappingException( - String.format( - Locale.ROOT, - "Style [%s] should not be specified with custom UUID value generator : %s.%s", - config.style().name(), - idMember.getDeclaringClass().getName(), - idMember.getName() - ) - ); - } - generator = instantiateCustomGenerator( config.algorithm() ); - } - else if ( config.style() == TIME ) { - generator = new CustomVersionOneStrategy(); - } - else { - generator = StandardRandomStrategy.INSTANCE; - } - - final Class propertyType = getPropertyType( idMember ); - this.valueTransformer = determineProperTransformer( propertyType ); - } - private static UuidValueGenerator instantiateCustomGenerator(Class algorithmClass) { try { return algorithmClass.getDeclaredConstructor().newInstance(); @@ -147,34 +165,4 @@ public class UuidGenerator implements BeforeExecutionGenerator { throw new HibernateException( "Unanticipated return type [" + propertyType.getName() + "] for UUID conversion" ); } - - public UuidGenerator( - org.hibernate.annotations.UuidGenerator config, - Member member, - GeneratorCreationContext creationContext) { - this(config, member); - } - - /** - * @return {@link EventTypeSets#INSERT_ONLY} - */ - @Override - public EnumSet getEventTypes() { - return INSERT_ONLY; - } - - @Override - public Object generate(SharedSessionContractImplementor session, Object owner, Object currentValue, EventType eventType) { - return valueTransformer.transform( generator.generateUuid( session ) ); - } - - @Internal - public UuidValueGenerator getValueGenerator() { - return generator; - } - - @Internal - public ValueTransformer getValueTransformer() { - return valueTransformer; - } }