HHH-15782 make @ValueGenerationType work with the new "split" hierarchy of value generators

this was a lot easier than I thought it would be
This commit is contained in:
Gavin 2022-11-30 00:34:05 +01:00 committed by Gavin King
parent 82db252422
commit f022d6ef3b
13 changed files with 166 additions and 135 deletions

View File

@ -13,8 +13,9 @@ import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.spi.JdbcCoordinator; import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.tuple.AnnotationValueGeneration; import org.hibernate.tuple.AnnotationValueGenerationStrategy;
import org.hibernate.tuple.GenerationTiming; import org.hibernate.tuple.GenerationTiming;
import org.hibernate.tuple.InMemoryValueGenerationStrategy;
import org.hibernate.tuple.TimestampGenerators; import org.hibernate.tuple.TimestampGenerators;
import org.hibernate.tuple.ValueGenerator; import org.hibernate.tuple.ValueGenerator;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
@ -42,7 +43,8 @@ import static org.hibernate.tuple.GenerationTiming.ALWAYS;
*/ */
@Deprecated(since = "6.2") @Deprecated(since = "6.2")
@Internal @Internal
public class SourceGeneration implements AnnotationValueGeneration<Source>, ValueGenerator<Object> { public class SourceGeneration
implements AnnotationValueGenerationStrategy<Source>, InMemoryValueGenerationStrategy, ValueGenerator<Object> {
private static final CoreMessageLogger log = Logger.getMessageLogger( private static final CoreMessageLogger log = Logger.getMessageLogger(
CoreMessageLogger.class, CoreMessageLogger.class,
@ -53,6 +55,10 @@ public class SourceGeneration implements AnnotationValueGeneration<Source>, Valu
private ValueGenerator<?> valueGenerator; private ValueGenerator<?> valueGenerator;
@Override @Override
public void initialize(Source annotation, Class<?> propertyType, String entityName, String propertyName) {
initialize( annotation, propertyType );
}
public void initialize(Source annotation, Class<?> propertyType) { public void initialize(Source annotation, Class<?> propertyType) {
this.propertyType = propertyType; this.propertyType = propertyType;
switch ( annotation.value() ) { switch ( annotation.value() ) {
@ -77,16 +83,6 @@ public class SourceGeneration implements AnnotationValueGeneration<Source>, Valu
return valueGenerator; return valueGenerator;
} }
@Override
public boolean referenceColumnInSql() {
return true;
}
@Override
public String getDatabaseGeneratedReferencedColumnValue() {
return null;
}
@Override @Override
public Object generateValue(Session session, Object owner) { public Object generateValue(Session session, Object owner) {
SharedSessionContractImplementor implementor = (SharedSessionContractImplementor) session; SharedSessionContractImplementor implementor = (SharedSessionContractImplementor) session;

View File

@ -6,25 +6,25 @@
*/ */
package org.hibernate.annotations; package org.hibernate.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import org.hibernate.tuple.AnnotationValueGeneration; import org.hibernate.tuple.ValueGenerationStrategy;
import org.hibernate.tuple.ValueGeneration;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
/** /**
* Meta-annotation used to mark another annotation as providing configuration * Meta-annotation used to mark another annotation as providing configuration
* for a custom {@linkplain ValueGeneration value generation strategy}. This * for a custom {@linkplain ValueGenerationStrategy value generation strategy}.
* is the best way to work with customized value generation in Hibernate. * This is the best way to work with customized value generation in Hibernate.
* <p> * <p>
* For example, if we have a custom value generator: * For example, if we have a custom value generator:
* <pre>{@code * <pre>{@code
* public class SKUGeneration implements AnnotationValueGeneration<SKU>, ValueGenerator<String> { * public class SKUGeneration
* implements InMemoryValueGenerationStrategy,
* ValueGenerator<String> {
* ... * ...
* } * }
* }</pre> * }</pre>
@ -43,10 +43,18 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* property to be generated when any SQL statement to {@code insert} or * property to be generated when any SQL statement to {@code insert} or
* {@code update} the entity is executed. * {@code update} the entity is executed.
* <p> * <p>
* Each generator annotation type has an {@link AnnotationValueGeneration} * Every generator annotation type has an {@link ValueGenerationStrategy}
* implementation which is responsible for generating values. The generator * implementation which is responsible for generating values. It must be either:
* annotation may have members, which are used to configure the generator, * <ul>
* when {@link AnnotationValueGeneration#initialize} is called. * <li>an {@link org.hibernate.tuple.InMemoryValueGenerationStrategy}, for
* values that are generated in Java code, using a
* {@link org.hibernate.tuple.ValueGenerator}, or
* <li>an {@link org.hibernate.tuple.InDatabaseValueGenerationStrategy}, for
* values which are generated by the database.
* </ul>
* 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}.
* <p> * <p>
* There are several excellent examples of the use of this machinery right * There are several excellent examples of the use of this machinery right
* here in this package. {@link TenantId} and its corresponding generator * 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 * A {@code @ValueGenerationType} annotation must have retention policy
* {@link RetentionPolicy#RUNTIME}. * {@link RetentionPolicy#RUNTIME}.
* *
* @see ValueGenerationStrategy
* @see org.hibernate.tuple.InMemoryValueGenerationStrategy
* @see org.hibernate.tuple.InDatabaseValueGenerationStrategy
* @see org.hibernate.tuple.AnnotationValueGenerationStrategy
*
* @author Gunnar Morling * @author Gunnar Morling
*/ */
@Target(ANNOTATION_TYPE) @Target(ANNOTATION_TYPE)
@Retention(RUNTIME) @Retention(RUNTIME)
public @interface ValueGenerationType { public @interface ValueGenerationType {
/** /**
* The type of value generation associated with the annotated value generator annotation type. The referenced * A class that implements {@link ValueGenerationStrategy}.
* generation type must be parameterized with the type of the given generator annotation. * <p>
* * If the generator annotation has members used to configure the
* @return the value generation type * generation strategy instance, the strategy should implement
* {@link org.hibernate.tuple.AnnotationValueGenerationStrategy}.
*/ */
Class<? extends AnnotationValueGeneration<?>> generatedBy(); Class<? extends ValueGenerationStrategy> generatedBy();
} }

View File

@ -40,8 +40,8 @@ import org.hibernate.mapping.ToOne;
import org.hibernate.mapping.Value; import org.hibernate.mapping.Value;
import org.hibernate.metamodel.spi.EmbeddableInstantiator; import org.hibernate.metamodel.spi.EmbeddableInstantiator;
import org.hibernate.property.access.spi.PropertyAccessStrategy; import org.hibernate.property.access.spi.PropertyAccessStrategy;
import org.hibernate.tuple.AnnotationValueGenerationStrategy;
import org.hibernate.tuple.ValueGenerationStrategy; import org.hibernate.tuple.ValueGenerationStrategy;
import org.hibernate.tuple.AnnotationValueGeneration;
import org.hibernate.tuple.AttributeBinder; import org.hibernate.tuple.AttributeBinder;
import org.hibernate.tuple.InDatabaseValueGenerationStrategy; import org.hibernate.tuple.InDatabaseValueGenerationStrategy;
import org.hibernate.tuple.GenerationTiming; import org.hibernate.tuple.GenerationTiming;
@ -402,10 +402,10 @@ public class PropertyBinder {
/** /**
* Returns the value generation strategy for the given property, if any. * Returns the value generation strategy for the given property, if any.
*/ */
private ValueGeneration getValueGenerationFromAnnotations(XProperty property) { private ValueGenerationStrategy getValueGenerationFromAnnotations(XProperty property) {
AnnotationValueGeneration<?> valueGeneration = null; ValueGenerationStrategy valueGeneration = null;
for ( Annotation annotation : property.getAnnotations() ) { for ( Annotation annotation : property.getAnnotations() ) {
AnnotationValueGeneration<?> candidate = getValueGenerationFromAnnotation( property, annotation ); final ValueGenerationStrategy candidate = getValueGenerationFromAnnotation( property, annotation );
if ( candidate != null ) { if ( candidate != null ) {
if ( valueGeneration != null ) { if ( valueGeneration != null ) {
throw new AnnotationException( "Property '" + qualify( holder.getPath(), name ) 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 * 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. * applied to the given property is returned, {@code null} otherwise.
*/ */
private <A extends Annotation> AnnotationValueGeneration<A> getValueGenerationFromAnnotation( private ValueGenerationStrategy getValueGenerationFromAnnotation(
XProperty property, XProperty property,
A annotation) { Annotation annotation) {
final ValueGenerationType generatorAnnotation = annotation.annotationType().getAnnotation( ValueGenerationType.class ); final ValueGenerationType generatorAnnotation = annotation.annotationType().getAnnotation( ValueGenerationType.class );
if ( generatorAnnotation == null ) { if ( generatorAnnotation == null ) {
return null; return null;
} }
final Class<? extends AnnotationValueGeneration<?>> generationType = generatorAnnotation.generatedBy(); final ValueGenerationStrategy valueGeneration =
final AnnotationValueGeneration<A> valueGeneration = instantiateAndInitializeValueGeneration( annotation, generationType, property ); instantiateAndInitializeValueGeneration( annotation, generatorAnnotation.generatedBy(), property );
if ( annotation.annotationType() == Generated.class && property.isAnnotationPresent(Version.class) ) { if ( annotation.annotationType() == Generated.class && property.isAnnotationPresent(Version.class) ) {
switch ( valueGeneration.getGenerationTiming() ) { 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 * Instantiates the given generator annotation type, initializing it with the given instance of the corresponding
* generator annotation and the property's type. * generator annotation and the property's type.
*/ */
private <A extends Annotation> AnnotationValueGeneration<A> instantiateAndInitializeValueGeneration( private <A extends Annotation> ValueGenerationStrategy instantiateAndInitializeValueGeneration(
A annotation, A annotation,
Class<? extends AnnotationValueGeneration<?>> generationType, Class<? extends ValueGenerationStrategy> generationType,
XProperty property) { XProperty property) {
try { try {
// This will cause a CCE in case the generation type doesn't match the annotation type; As this would be a final ValueGenerationStrategy valueGeneration = generationType.newInstance();
// programming error of the generation type developer and thus should show up during testing, we don't 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 // check this explicitly; If required, this could be done e.g. using ClassMate
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
AnnotationValueGeneration<A> valueGeneration = (AnnotationValueGeneration<A>) generationType.newInstance(); final AnnotationValueGenerationStrategy<A> generation = (AnnotationValueGenerationStrategy<A>) valueGeneration;
valueGeneration.initialize( generation.initialize(
annotation, annotation,
buildingContext.getBootstrapContext().getReflectionManager().toClass( property.getType() ), buildingContext.getBootstrapContext().getReflectionManager().toClass( property.getType() ),
entityBinder.getPersistentClass().getEntityName(), entityBinder.getPersistentClass().getEntityName(),
property.getName() property.getName()
); );
}
return valueGeneration; return valueGeneration;
} }

View File

@ -14,18 +14,19 @@ import java.lang.annotation.Annotation;
* *
* @param <A> The generator annotation type supported by an implementation * @param <A> The generator annotation type supported by an implementation
* *
* @see org.hibernate.annotations.ValueGenerationType
*
* @author Gunnar Morling * @author Gunnar Morling
*/ */
public interface AnnotationValueGeneration<A extends Annotation> extends ValueGeneration { public interface AnnotationValueGeneration<A extends Annotation>
extends ValueGeneration, AnnotationValueGenerationStrategy<A> {
/** /**
* Initializes this generation strategy for the given annotation instance. * 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. * annotation's attribute values and store them in fields.
* @param propertyType the type of the property annotated with the generator annotation. Implementations may use * @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 * @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.
*/ */
@ -34,7 +35,7 @@ public interface AnnotationValueGeneration<A extends Annotation> extends ValueGe
/** /**
* Initializes this generation strategy for the given annotation instance. * 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. * annotation's attribute values and store them in fields.
* @param propertyType the type of the property annotated with the generator annotation. Implementations may use * @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.

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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 <A> 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<A extends Annotation> 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);
}

View File

@ -7,37 +7,35 @@
package org.hibernate.tuple; package org.hibernate.tuple;
import org.hibernate.annotations.GeneratedColumn; import org.hibernate.annotations.GeneratedColumn;
import org.hibernate.dialect.Dialect;
/** /**
* For {@link GeneratedColumn} * For {@link GeneratedColumn}.
* *
* @author Gavin King * @author Gavin King
*/ */
public class GeneratedAlwaysValueGeneration implements AnnotationValueGeneration<GeneratedColumn> { public class GeneratedAlwaysValueGeneration
implements InDatabaseValueGenerationStrategy {
public GeneratedAlwaysValueGeneration() {} public GeneratedAlwaysValueGeneration() {}
@Override
public void initialize(GeneratedColumn annotation, Class<?> propertyType) {}
@Override @Override
public GenerationTiming getGenerationTiming() { public GenerationTiming getGenerationTiming() {
return GenerationTiming.ALWAYS; return GenerationTiming.ALWAYS;
} }
@Override @Override
public ValueGenerator<?> getValueGenerator() { public boolean writePropertyValue() {
// database generated values do not have a value generator
return null;
}
@Override
public boolean referenceColumnInSql() {
return false; return false;
} }
@Override @Override
public String getDatabaseGeneratedReferencedColumnValue() { public boolean referenceColumnsInSql() {
return false;
}
@Override
public String[] getReferencedColumnValues(Dialect dialect) {
return null; return null;
} }
} }

View File

@ -7,6 +7,7 @@
package org.hibernate.tuple; package org.hibernate.tuple;
import org.hibernate.annotations.Generated; import org.hibernate.annotations.Generated;
import org.hibernate.dialect.Dialect;
import static org.hibernate.internal.util.StringHelper.isEmpty; import static org.hibernate.internal.util.StringHelper.isEmpty;
@ -16,11 +17,12 @@ import static org.hibernate.internal.util.StringHelper.isEmpty;
* @author Steve Ebersole * @author Steve Ebersole
* @author Gunnar Morling * @author Gunnar Morling
*/ */
public class GeneratedValueGeneration implements AnnotationValueGeneration<Generated> { public class GeneratedValueGeneration
implements AnnotationValueGenerationStrategy<Generated>, InDatabaseValueGenerationStrategy {
private GenerationTiming timing; private GenerationTiming timing;
private boolean writable; private boolean writable;
private String sql; private String[] sql;
public GeneratedValueGeneration() { public GeneratedValueGeneration() {
} }
@ -30,9 +32,9 @@ public class GeneratedValueGeneration implements AnnotationValueGeneration<Gener
} }
@Override @Override
public void initialize(Generated annotation, Class<?> propertyType) { public void initialize(Generated annotation, Class<?> propertyType, String entityName, String propertyName) {
timing = annotation.value().getEquivalent(); 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; writable = annotation.writable() || sql != null;
} }
@ -42,19 +44,18 @@ public class GeneratedValueGeneration implements AnnotationValueGeneration<Gener
} }
@Override @Override
public ValueGenerator<?> getValueGenerator() { public boolean referenceColumnsInSql() {
// database generated values do not have a value generator
return null;
}
@Override
public boolean referenceColumnInSql() {
return writable; return writable;
} }
@Override @Override
public String getDatabaseGeneratedReferencedColumnValue() { public String[] getReferencedColumnValues(Dialect dialect) {
return sql; return sql;
} }
@Override
public boolean writePropertyValue() {
return writable && sql==null;
}
} }

View File

@ -16,6 +16,8 @@ import org.hibernate.dialect.Dialect;
* {@code select}. * {@code select}.
* *
* @author Steve Ebersole * @author Steve Ebersole
*
* @since 6.2
*/ */
public interface InDatabaseValueGenerationStrategy extends ValueGenerationStrategy { public interface InDatabaseValueGenerationStrategy extends ValueGenerationStrategy {

View File

@ -12,6 +12,8 @@ package org.hibernate.tuple;
* or property value. * or property value.
* *
* @author Steve Ebersole * @author Steve Ebersole
*
* @since 6.2
*/ */
public interface InMemoryValueGenerationStrategy extends ValueGenerationStrategy { public interface InMemoryValueGenerationStrategy extends ValueGenerationStrategy {

View File

@ -19,7 +19,8 @@ import org.hibernate.type.descriptor.java.JavaType;
* *
* @author Gavin King * @author Gavin King
*/ */
public class TenantIdGeneration implements AnnotationValueGeneration<TenantId>, ValueGenerator<Object> { public class TenantIdGeneration
implements AnnotationValueGenerationStrategy<TenantId>, InMemoryValueGenerationStrategy, ValueGenerator<Object> {
private String entityName; private String entityName;
private String propertyName; private String propertyName;
@ -32,11 +33,6 @@ public class TenantIdGeneration implements AnnotationValueGeneration<TenantId>,
this.propertyType = propertyType; this.propertyType = propertyType;
} }
@Override
public void initialize(TenantId annotation, Class<?> propertyType) {
throw new UnsupportedOperationException();
}
@Override @Override
public GenerationTiming getGenerationTiming() { public GenerationTiming getGenerationTiming() {
return GenerationTiming.INSERT; return GenerationTiming.INSERT;
@ -79,14 +75,4 @@ public class TenantIdGeneration implements AnnotationValueGeneration<TenantId>,
public Object generateValue(Session session, Object owner) { public Object generateValue(Session session, Object owner) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public boolean referenceColumnInSql() {
return false;
}
@Override
public String getDatabaseGeneratedReferencedColumnValue() {
return null;
}
} }

View File

@ -10,7 +10,9 @@ import java.io.Serializable;
/** /**
* Describes the generation of values of a certain field or property of an entity. A generated * 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.
* <ul> * <ul>
* <li>Java value generation is the responsibility of an associated {@link ValueGenerator}. * <li>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 * In this case, the generated value is written to the database just like any other field
@ -21,6 +23,9 @@ import java.io.Serializable;
* statement. In this case, the generated value is retrieved from the database using a SQL * statement. In this case, the generated value is retrieved from the database using a SQL
* {@code select}. * {@code select}.
* </ul> * </ul>
* 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.ValueGenerationType
* @see org.hibernate.annotations.Generated * @see org.hibernate.annotations.Generated
@ -28,6 +33,8 @@ import java.io.Serializable;
* *
* @author Steve Ebersole * @author Steve Ebersole
* @author Gavin King * @author Gavin King
*
* @since 6.2
*/ */
public interface ValueGenerationStrategy extends Serializable { public interface ValueGenerationStrategy extends Serializable {
/** /**

View File

@ -13,21 +13,20 @@ import org.hibernate.annotations.GeneratorType;
import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.ReflectHelper;
/** /**
* A {@link AnnotationValueGeneration} which allows to specify the {@link ValueGenerator} to be used to determine the * An {@link AnnotationValueGeneration} which delegates to a {@link ValueGenerator}.
* value of the annotated property.
* *
* @author Gunnar Morling * @author Gunnar Morling
*/ */
public class VmValueGeneration implements AnnotationValueGeneration<GeneratorType> { public class VmValueGeneration
implements AnnotationValueGenerationStrategy<GeneratorType>, InMemoryValueGenerationStrategy {
private GenerationTiming generationTiming; private GenerationTiming generationTiming;
private Constructor<? extends ValueGenerator<?>> constructor; private Constructor<? extends ValueGenerator<?>> constructor;
@Override @Override
public void initialize(GeneratorType annotation, Class<?> propertyType) { public void initialize(GeneratorType annotation, Class<?> propertyType, String entityName, String propertyName) {
Class<? extends ValueGenerator<?>> generatorType = annotation.type(); constructor = ReflectHelper.getDefaultConstructor( annotation.type() );
constructor = ReflectHelper.getDefaultConstructor( generatorType ); generationTiming = annotation.when().getEquivalent();
this.generationTiming = annotation.when().getEquivalent();
} }
@Override @Override
@ -44,14 +43,4 @@ public class VmValueGeneration implements AnnotationValueGeneration<GeneratorTyp
throw new HibernateException( "Couldn't instantiate value generator", e ); throw new HibernateException( "Couldn't instantiate value generator", e );
} }
} }
@Override
public boolean referenceColumnInSql() {
return false;
}
@Override
public String getDatabaseGeneratedReferencedColumnValue() {
return null;
}
} }

View File

@ -19,8 +19,9 @@ import jakarta.persistence.Table;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.annotations.ValueGenerationType; import org.hibernate.annotations.ValueGenerationType;
import org.hibernate.tuple.AnnotationValueGeneration; import org.hibernate.tuple.AnnotationValueGenerationStrategy;
import org.hibernate.tuple.GenerationTiming; import org.hibernate.tuple.GenerationTiming;
import org.hibernate.tuple.InMemoryValueGenerationStrategy;
import org.hibernate.tuple.ValueGenerator; import org.hibernate.tuple.ValueGenerator;
import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.DomainModel;
@ -86,11 +87,12 @@ public class GeneratedUuidTests {
//end::mapping-generated-custom-ex2[] //end::mapping-generated-custom-ex2[]
//tag::mapping-generated-custom-ex3[] //tag::mapping-generated-custom-ex3[]
public static class UuidValueGeneration implements AnnotationValueGeneration<GeneratedUuidValue>, ValueGenerator<UUID> { public static class UuidValueGeneration
implements AnnotationValueGenerationStrategy<GeneratedUuidValue>, InMemoryValueGenerationStrategy, ValueGenerator<UUID> {
private GenerationTiming timing; private GenerationTiming timing;
@Override @Override
public void initialize(GeneratedUuidValue annotation, Class<?> propertyType) { public void initialize(GeneratedUuidValue annotation, Class<?> propertyType, String entityName, String propertyName) {
timing = annotation.timing(); timing = annotation.timing();
} }
@ -104,16 +106,6 @@ public class GeneratedUuidTests {
return this; return this;
} }
@Override
public boolean referenceColumnInSql() {
return false;
}
@Override
public String getDatabaseGeneratedReferencedColumnValue() {
return null;
}
@Override @Override
public UUID generateValue(Session session, Object owner) { public UUID generateValue(Session session, Object owner) {
return UUID.randomUUID(); return UUID.randomUUID();