diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/SourceGeneration.java b/hibernate-core/src/main/java/org/hibernate/annotations/SourceGeneration.java index 861ee133c0..47b375ca98 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/SourceGeneration.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/SourceGeneration.java @@ -13,8 +13,9 @@ import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.spi.JdbcCoordinator; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.CoreMessageLogger; -import org.hibernate.tuple.AnnotationValueGeneration; +import org.hibernate.tuple.AnnotationValueGenerationStrategy; import org.hibernate.tuple.GenerationTiming; +import org.hibernate.tuple.InMemoryValueGenerationStrategy; import org.hibernate.tuple.TimestampGenerators; import org.hibernate.tuple.ValueGenerator; import org.jboss.logging.Logger; @@ -42,7 +43,8 @@ import static org.hibernate.tuple.GenerationTiming.ALWAYS; */ @Deprecated(since = "6.2") @Internal -public class SourceGeneration implements AnnotationValueGeneration, ValueGenerator { +public class SourceGeneration + implements AnnotationValueGenerationStrategy, InMemoryValueGenerationStrategy, ValueGenerator { private static final CoreMessageLogger log = Logger.getMessageLogger( CoreMessageLogger.class, @@ -53,6 +55,10 @@ public class SourceGeneration implements AnnotationValueGeneration, Valu private ValueGenerator valueGenerator; @Override + public void initialize(Source annotation, Class propertyType, String entityName, String propertyName) { + initialize( annotation, propertyType ); + } + public void initialize(Source annotation, Class propertyType) { this.propertyType = propertyType; switch ( annotation.value() ) { @@ -77,16 +83,6 @@ public class SourceGeneration implements AnnotationValueGeneration, Valu return valueGenerator; } - @Override - public boolean referenceColumnInSql() { - return true; - } - - @Override - public String getDatabaseGeneratedReferencedColumnValue() { - return null; - } - @Override public Object generateValue(Session session, Object owner) { SharedSessionContractImplementor implementor = (SharedSessionContractImplementor) session; diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/ValueGenerationType.java b/hibernate-core/src/main/java/org/hibernate/annotations/ValueGenerationType.java index b452eb0eaa..6dfb564cbe 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/ValueGenerationType.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/ValueGenerationType.java @@ -6,25 +6,25 @@ */ package org.hibernate.annotations; -import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import org.hibernate.tuple.AnnotationValueGeneration; -import org.hibernate.tuple.ValueGeneration; +import org.hibernate.tuple.ValueGenerationStrategy; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Meta-annotation used to mark another annotation as providing configuration - * for a custom {@linkplain ValueGeneration value generation strategy}. This - * is the best way to work with customized value generation in Hibernate. + * for a custom {@linkplain ValueGenerationStrategy value generation strategy}. + * This is the best way to work with customized value generation in Hibernate. *

* For example, if we have a custom value generator: *

{@code
- * public class SKUGeneration implements AnnotationValueGeneration, ValueGenerator {
+ * public class SKUGeneration
+ *         implements InMemoryValueGenerationStrategy,
+ *                    ValueGenerator {
  *     ...
  * }
  * }
@@ -43,10 +43,18 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; * property to be generated when any SQL statement to {@code insert} or * {@code update} the entity is executed. *

- * Each generator annotation type has an {@link AnnotationValueGeneration} - * implementation which is responsible for generating values. The generator - * annotation may have members, which are used to configure the generator, - * when {@link AnnotationValueGeneration#initialize} is called. + * Every generator annotation type has an {@link ValueGenerationStrategy} + * implementation which is responsible for generating values. It must be either: + *

+ * A generator annotation may have members, which are used to configure the + * generation strategy, when the strategy instance in initialized via + * {@link org.hibernate.tuple.AnnotationValueGenerationStrategy#initialize}. *

* There are several excellent examples of the use of this machinery right * here in this package. {@link TenantId} and its corresponding generator @@ -55,16 +63,22 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; * A {@code @ValueGenerationType} annotation must have retention policy * {@link RetentionPolicy#RUNTIME}. * + * @see ValueGenerationStrategy + * @see org.hibernate.tuple.InMemoryValueGenerationStrategy + * @see org.hibernate.tuple.InDatabaseValueGenerationStrategy + * @see org.hibernate.tuple.AnnotationValueGenerationStrategy + * * @author Gunnar Morling */ @Target(ANNOTATION_TYPE) @Retention(RUNTIME) public @interface ValueGenerationType { /** - * The type of value generation associated with the annotated value generator annotation type. The referenced - * generation type must be parameterized with the type of the given generator annotation. - * - * @return the value generation type + * A class that implements {@link ValueGenerationStrategy}. + *

+ * If the generator annotation has members used to configure the + * generation strategy instance, the strategy should implement + * {@link org.hibernate.tuple.AnnotationValueGenerationStrategy}. */ - Class> generatedBy(); + Class generatedBy(); } diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java index f1f413e4b0..60ba576089 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java @@ -40,8 +40,8 @@ import org.hibernate.mapping.ToOne; import org.hibernate.mapping.Value; import org.hibernate.metamodel.spi.EmbeddableInstantiator; import org.hibernate.property.access.spi.PropertyAccessStrategy; +import org.hibernate.tuple.AnnotationValueGenerationStrategy; import org.hibernate.tuple.ValueGenerationStrategy; -import org.hibernate.tuple.AnnotationValueGeneration; import org.hibernate.tuple.AttributeBinder; import org.hibernate.tuple.InDatabaseValueGenerationStrategy; import org.hibernate.tuple.GenerationTiming; @@ -402,10 +402,10 @@ public class PropertyBinder { /** * Returns the value generation strategy for the given property, if any. */ - private ValueGeneration getValueGenerationFromAnnotations(XProperty property) { - AnnotationValueGeneration valueGeneration = null; + private ValueGenerationStrategy getValueGenerationFromAnnotations(XProperty property) { + ValueGenerationStrategy valueGeneration = null; for ( Annotation annotation : property.getAnnotations() ) { - AnnotationValueGeneration candidate = getValueGenerationFromAnnotation( property, annotation ); + final ValueGenerationStrategy candidate = getValueGenerationFromAnnotation( property, annotation ); if ( candidate != null ) { if ( valueGeneration != null ) { throw new AnnotationException( "Property '" + qualify( holder.getPath(), name ) @@ -423,16 +423,16 @@ public class PropertyBinder { * 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. */ - private AnnotationValueGeneration getValueGenerationFromAnnotation( + private ValueGenerationStrategy getValueGenerationFromAnnotation( XProperty property, - A annotation) { + Annotation annotation) { final ValueGenerationType generatorAnnotation = annotation.annotationType().getAnnotation( ValueGenerationType.class ); if ( generatorAnnotation == null ) { return null; } - final Class> generationType = generatorAnnotation.generatedBy(); - final AnnotationValueGeneration valueGeneration = instantiateAndInitializeValueGeneration( annotation, generationType, property ); + final ValueGenerationStrategy valueGeneration = + instantiateAndInitializeValueGeneration( annotation, generatorAnnotation.generatedBy(), property ); if ( annotation.annotationType() == Generated.class && property.isAnnotationPresent(Version.class) ) { switch ( valueGeneration.getGenerationTiming() ) { @@ -456,23 +456,26 @@ public class PropertyBinder { * Instantiates the given generator annotation type, initializing it with the given instance of the corresponding * generator annotation and the property's type. */ - private AnnotationValueGeneration instantiateAndInitializeValueGeneration( + private ValueGenerationStrategy instantiateAndInitializeValueGeneration( A annotation, - Class> generationType, + Class generationType, XProperty property) { try { - // 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 - // check this explicitly; If required, this could be done e.g. using ClassMate - @SuppressWarnings( "unchecked" ) - AnnotationValueGeneration valueGeneration = (AnnotationValueGeneration) generationType.newInstance(); - valueGeneration.initialize( - annotation, - buildingContext.getBootstrapContext().getReflectionManager().toClass( property.getType() ), - entityBinder.getPersistentClass().getEntityName(), - property.getName() - ); + final ValueGenerationStrategy valueGeneration = generationType.newInstance(); + if ( valueGeneration instanceof AnnotationValueGenerationStrategy ) { + // 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 + // check this explicitly; If required, this could be done e.g. using ClassMate + @SuppressWarnings("unchecked") + final AnnotationValueGenerationStrategy generation = (AnnotationValueGenerationStrategy) valueGeneration; + generation.initialize( + annotation, + buildingContext.getBootstrapContext().getReflectionManager().toClass( property.getType() ), + entityBinder.getPersistentClass().getEntityName(), + property.getName() + ); + } return valueGeneration; } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/AnnotationValueGeneration.java b/hibernate-core/src/main/java/org/hibernate/tuple/AnnotationValueGeneration.java index 19241b484d..4029897fe7 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/AnnotationValueGeneration.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/AnnotationValueGeneration.java @@ -14,27 +14,28 @@ import java.lang.annotation.Annotation; * * @param The generator annotation type supported by an implementation * + * @see org.hibernate.annotations.ValueGenerationType + * * @author Gunnar Morling */ -public interface AnnotationValueGeneration extends ValueGeneration { - +public interface AnnotationValueGeneration + extends ValueGeneration, AnnotationValueGenerationStrategy { /** * Initializes this generation strategy for the given annotation instance. * - * @param annotation an instance of the strategy's annotation type. Typically implementations will retrieve the - * annotation's attribute values and store them in fields. + * @param annotation an instance of the strategy's annotation type. Typically, implementations will retrieve the + * annotation's attribute values and store them in fields. * @param propertyType the type of the property annotated with the generator annotation. Implementations may use - * the type to determine the right {@link ValueGenerator} to be applied. - * + * the type to determine the right {@link ValueGenerator} to be applied. * @throws org.hibernate.HibernateException in case an error occurred during initialization, e.g. if - * an implementation can't create a value for the given property type. + * an implementation can't create a value for the given property type. */ void initialize(A annotation, Class propertyType); /** * Initializes this generation strategy for the given annotation instance. * - * @param annotation an instance of the strategy's annotation type. Typically implementations will retrieve the + * @param annotation an instance of the strategy's annotation type. Typically, implementations will retrieve the * annotation's attribute values and store them in fields. * @param propertyType the type of the property annotated with the generator annotation. Implementations may use * the type to determine the right {@link ValueGenerator} to be applied. @@ -45,6 +46,6 @@ public interface AnnotationValueGeneration extends ValueGe * an implementation can't create a value for the given property type. */ default void initialize(A annotation, Class propertyType, String entityName, String propertyName) { - initialize(annotation, propertyType); + initialize( annotation, propertyType ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/AnnotationValueGenerationStrategy.java b/hibernate-core/src/main/java/org/hibernate/tuple/AnnotationValueGenerationStrategy.java new file mode 100644 index 0000000000..06ee14ded6 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/tuple/AnnotationValueGenerationStrategy.java @@ -0,0 +1,40 @@ +/* + * 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 . + */ +package org.hibernate.tuple; + +import java.lang.annotation.Annotation; + + +/** + * A {@link ValueGenerationStrategy} based on a custom Java generator annotation type. + * Every instance must implement either {@link InMemoryValueGenerationStrategy} or + * {@link InDatabaseValueGenerationStrategy}. + * + * @param The generator annotation type supported by an implementation + * + * @see org.hibernate.annotations.ValueGenerationType + * + * @author Gunnar Morling + * @author Gavin King + * + * @since 6.2 + */ +public interface AnnotationValueGenerationStrategy extends ValueGenerationStrategy { + /** + * Initializes this generation strategy for the given annotation instance. + * + * @param annotation an instance of the strategy's annotation type. Typically, implementations will retrieve the + * annotation's attribute values and store them in fields. + * @param propertyType the type of the property annotated with the generator annotation. Implementations may use + * the type to determine the right {@link ValueGenerator} to be applied. + * @param entityName the name of the entity to which the annotated property belongs + * @param propertyName the name of the annotated property + * @throws org.hibernate.HibernateException in case an error occurred during initialization, e.g. if + * an implementation can't create a value for the given property type. + */ + void initialize(A annotation, Class propertyType, String entityName, String propertyName); +} diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/GeneratedAlwaysValueGeneration.java b/hibernate-core/src/main/java/org/hibernate/tuple/GeneratedAlwaysValueGeneration.java index 30cf7ad6e5..fd5de52d63 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/GeneratedAlwaysValueGeneration.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/GeneratedAlwaysValueGeneration.java @@ -7,37 +7,35 @@ package org.hibernate.tuple; import org.hibernate.annotations.GeneratedColumn; +import org.hibernate.dialect.Dialect; /** - * For {@link GeneratedColumn} + * For {@link GeneratedColumn}. * * @author Gavin King */ -public class GeneratedAlwaysValueGeneration implements AnnotationValueGeneration { +public class GeneratedAlwaysValueGeneration + implements InDatabaseValueGenerationStrategy { public GeneratedAlwaysValueGeneration() {} - @Override - public void initialize(GeneratedColumn annotation, Class propertyType) {} - @Override public GenerationTiming getGenerationTiming() { return GenerationTiming.ALWAYS; } @Override - public ValueGenerator getValueGenerator() { - // database generated values do not have a value generator - return null; - } - - @Override - public boolean referenceColumnInSql() { + public boolean writePropertyValue() { return false; } @Override - public String getDatabaseGeneratedReferencedColumnValue() { + public boolean referenceColumnsInSql() { + return false; + } + + @Override + public String[] getReferencedColumnValues(Dialect dialect) { return null; } } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/GeneratedValueGeneration.java b/hibernate-core/src/main/java/org/hibernate/tuple/GeneratedValueGeneration.java index 6c4caafb58..947a3663be 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/GeneratedValueGeneration.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/GeneratedValueGeneration.java @@ -7,6 +7,7 @@ package org.hibernate.tuple; import org.hibernate.annotations.Generated; +import org.hibernate.dialect.Dialect; import static org.hibernate.internal.util.StringHelper.isEmpty; @@ -16,11 +17,12 @@ import static org.hibernate.internal.util.StringHelper.isEmpty; * @author Steve Ebersole * @author Gunnar Morling */ -public class GeneratedValueGeneration implements AnnotationValueGeneration { +public class GeneratedValueGeneration + implements AnnotationValueGenerationStrategy, InDatabaseValueGenerationStrategy { private GenerationTiming timing; private boolean writable; - private String sql; + private String[] sql; public GeneratedValueGeneration() { } @@ -30,9 +32,9 @@ public class GeneratedValueGeneration implements AnnotationValueGeneration propertyType) { + public void initialize(Generated annotation, Class propertyType, String entityName, String propertyName) { timing = annotation.value().getEquivalent(); - sql = isEmpty( annotation.sql() ) ? null : annotation.sql(); + sql = isEmpty( annotation.sql() ) ? null : new String[] { annotation.sql() }; writable = annotation.writable() || sql != null; } @@ -42,19 +44,18 @@ public class GeneratedValueGeneration implements AnnotationValueGeneration getValueGenerator() { - // database generated values do not have a value generator - return null; - } - - @Override - public boolean referenceColumnInSql() { + public boolean referenceColumnsInSql() { return writable; } @Override - public String getDatabaseGeneratedReferencedColumnValue() { + public String[] getReferencedColumnValues(Dialect dialect) { return sql; } + + @Override + public boolean writePropertyValue() { + return writable && sql==null; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/InDatabaseValueGenerationStrategy.java b/hibernate-core/src/main/java/org/hibernate/tuple/InDatabaseValueGenerationStrategy.java index e37f1bbc98..b63c0038a8 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/InDatabaseValueGenerationStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/InDatabaseValueGenerationStrategy.java @@ -16,6 +16,8 @@ import org.hibernate.dialect.Dialect; * {@code select}. * * @author Steve Ebersole + * + * @since 6.2 */ public interface InDatabaseValueGenerationStrategy extends ValueGenerationStrategy { diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/InMemoryValueGenerationStrategy.java b/hibernate-core/src/main/java/org/hibernate/tuple/InMemoryValueGenerationStrategy.java index dac8093783..3c65b5d494 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/InMemoryValueGenerationStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/InMemoryValueGenerationStrategy.java @@ -12,6 +12,8 @@ package org.hibernate.tuple; * or property value. * * @author Steve Ebersole + * + * @since 6.2 */ public interface InMemoryValueGenerationStrategy extends ValueGenerationStrategy { diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/TenantIdGeneration.java b/hibernate-core/src/main/java/org/hibernate/tuple/TenantIdGeneration.java index 967e26a738..219d2eb727 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/TenantIdGeneration.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/TenantIdGeneration.java @@ -19,7 +19,8 @@ import org.hibernate.type.descriptor.java.JavaType; * * @author Gavin King */ -public class TenantIdGeneration implements AnnotationValueGeneration, ValueGenerator { +public class TenantIdGeneration + implements AnnotationValueGenerationStrategy, InMemoryValueGenerationStrategy, ValueGenerator { private String entityName; private String propertyName; @@ -32,11 +33,6 @@ public class TenantIdGeneration implements AnnotationValueGeneration, this.propertyType = propertyType; } - @Override - public void initialize(TenantId annotation, Class propertyType) { - throw new UnsupportedOperationException(); - } - @Override public GenerationTiming getGenerationTiming() { return GenerationTiming.INSERT; @@ -79,14 +75,4 @@ public class TenantIdGeneration implements AnnotationValueGeneration, public Object generateValue(Session session, Object owner) { throw new UnsupportedOperationException(); } - - @Override - public boolean referenceColumnInSql() { - return false; - } - - @Override - public String getDatabaseGeneratedReferencedColumnValue() { - return null; - } } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/ValueGenerationStrategy.java b/hibernate-core/src/main/java/org/hibernate/tuple/ValueGenerationStrategy.java index f2404548db..0cce5b7dd8 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/ValueGenerationStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/ValueGenerationStrategy.java @@ -10,17 +10,22 @@ import java.io.Serializable; /** * Describes the generation of values of a certain field or property of an entity. A generated - * value might be generated in Java, or by the database. + * value might be generated in Java, or by the database. Every instance must implement either + * {@link InMemoryValueGenerationStrategy} or {@link InDatabaseValueGenerationStrategy} + * depending on whether values are generated in Java code, or by the database. *
    *
  • Java value generation is the responsibility of an associated {@link ValueGenerator}. - * In this case, the generated value is written to the database just like any other field - * or property value. + * In this case, the generated value is written to the database just like any other field + * or property value. *
  • A value generated by the database might be generated implicitly, by a trigger, or using - * a {@code default} column value specified in DDL, for example, or it might be generated - * by a SQL expression occurring explicitly in the SQL {@code insert} or {@code update} - * statement. In this case, the generated value is retrieved from the database using a SQL - * {@code select}. + * a {@code default} column value specified in DDL, for example, or it might be generated + * by a SQL expression occurring explicitly in the SQL {@code insert} or {@code update} + * statement. In this case, the generated value is retrieved from the database using a SQL + * {@code select}. *
+ * If an implementation of {@code ValueGenerationStrategy} may be associated with an entity + * via a {@linkplain org.hibernate.annotations.ValueGenerationType custom annotation}, it + * should implement {@link AnnotationValueGenerationStrategy}. * * @see org.hibernate.annotations.ValueGenerationType * @see org.hibernate.annotations.Generated @@ -28,6 +33,8 @@ import java.io.Serializable; * * @author Steve Ebersole * @author Gavin King + * + * @since 6.2 */ public interface ValueGenerationStrategy extends Serializable { /** diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/VmValueGeneration.java b/hibernate-core/src/main/java/org/hibernate/tuple/VmValueGeneration.java index 4da686d053..527f9d5bbe 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/VmValueGeneration.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/VmValueGeneration.java @@ -13,21 +13,20 @@ import org.hibernate.annotations.GeneratorType; import org.hibernate.internal.util.ReflectHelper; /** - * A {@link AnnotationValueGeneration} which allows to specify the {@link ValueGenerator} to be used to determine the - * value of the annotated property. + * An {@link AnnotationValueGeneration} which delegates to a {@link ValueGenerator}. * * @author Gunnar Morling */ -public class VmValueGeneration implements AnnotationValueGeneration { +public class VmValueGeneration + implements AnnotationValueGenerationStrategy, InMemoryValueGenerationStrategy { private GenerationTiming generationTiming; private Constructor> constructor; @Override - public void initialize(GeneratorType annotation, Class propertyType) { - Class> generatorType = annotation.type(); - constructor = ReflectHelper.getDefaultConstructor( generatorType ); - this.generationTiming = annotation.when().getEquivalent(); + public void initialize(GeneratorType annotation, Class propertyType, String entityName, String propertyName) { + constructor = ReflectHelper.getDefaultConstructor( annotation.type() ); + generationTiming = annotation.when().getEquivalent(); } @Override @@ -44,14 +43,4 @@ public class VmValueGeneration implements AnnotationValueGeneration, ValueGenerator { + public static class UuidValueGeneration + implements AnnotationValueGenerationStrategy, InMemoryValueGenerationStrategy, ValueGenerator { private GenerationTiming timing; @Override - public void initialize(GeneratedUuidValue annotation, Class propertyType) { + public void initialize(GeneratedUuidValue annotation, Class propertyType, String entityName, String propertyName) { timing = annotation.timing(); } @@ -104,16 +106,6 @@ public class GeneratedUuidTests { return this; } - @Override - public boolean referenceColumnInSql() { - return false; - } - - @Override - public String getDatabaseGeneratedReferencedColumnValue() { - return null; - } - @Override public UUID generateValue(Session session, Object owner) { return UUID.randomUUID();