HHH-15800 make Generator free of GenerationTiming
This commit is contained in:
parent
1104d01d33
commit
216fe0f615
|
@ -574,22 +574,27 @@ public class PropertyBinder {
|
||||||
|
|
||||||
private static void checkVersionGenerationAlways(XProperty property, Generator generator) {
|
private static void checkVersionGenerationAlways(XProperty property, Generator generator) {
|
||||||
if ( property.isAnnotationPresent(Version.class) ) {
|
if ( property.isAnnotationPresent(Version.class) ) {
|
||||||
final GenerationTiming timing = generator.getGenerationTiming();
|
if ( !generator.generatedOnInsert() ) {
|
||||||
if ( !timing.isAlways() ) {
|
|
||||||
throw new AnnotationException("Property '" + property.getName()
|
throw new AnnotationException("Property '" + property.getName()
|
||||||
+ "' is annotated '@Version' but has a value generator with timing " + timing.name()
|
+ "' is annotated '@Version' but has a 'Generator' which does not generate on inserts"
|
||||||
+ " (the value generation timing must be ALWAYS)"
|
);
|
||||||
|
}
|
||||||
|
if ( !generator.generatedOnUpdate() ) {
|
||||||
|
throw new AnnotationException("Property '" + property.getName()
|
||||||
|
+ "' is annotated '@Version' but has a 'Generator' which does not generate on updates"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void checkIdGeneratorTiming(Class<? extends Annotation> annotationType, Generator generator) {
|
private static void checkIdGeneratorTiming(Class<? extends Annotation> annotationType, Generator generator) {
|
||||||
GenerationTiming timing = generator.getGenerationTiming();
|
if ( !generator.generatedOnInsert() ) {
|
||||||
if ( timing != INSERT ) {
|
|
||||||
throw new MappingException( "Annotation '" + annotationType
|
throw new MappingException( "Annotation '" + annotationType
|
||||||
+ "' is annotated 'IdGeneratorType' but the given 'InMemoryGenerator' has timing " + timing
|
+ "' is annotated 'IdGeneratorType' but the given 'Generator' does not generate on inserts");
|
||||||
+ " (an id generator must having timing INSERT)");
|
}
|
||||||
|
if ( generator.generatedOnUpdate() ) {
|
||||||
|
throw new MappingException( "Annotation '" + annotationType
|
||||||
|
+ "' is annotated 'IdGeneratorType' but the given 'Generator' generates on updates (it must generate only on inserts)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,7 +129,7 @@ public final class Nullability {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean generated(Generator generator) {
|
private static boolean generated(Generator generator) {
|
||||||
return generator != null && generator.getGenerationTiming().isNotNever();
|
return generator != null && generator.isNotNever();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -19,8 +19,6 @@ import org.hibernate.tuple.GenerationTiming;
|
||||||
import org.hibernate.tuple.InMemoryGenerator;
|
import org.hibernate.tuple.InMemoryGenerator;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
import static org.hibernate.tuple.GenerationTiming.INSERT;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A classic extension point from the very earliest days of Hibernate,
|
* A classic extension point from the very earliest days of Hibernate,
|
||||||
* this interface is no longer the only way to generate identifiers. Any
|
* this interface is no longer the only way to generate identifiers. Any
|
||||||
|
@ -145,11 +143,19 @@ public interface IdentifierGenerator extends InMemoryGenerator, ExportableProduc
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {@link GenerationTiming#INSERT}
|
* @return {@code true}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
default GenerationTiming getGenerationTiming() {
|
default boolean generatedOnInsert() {
|
||||||
return INSERT;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code false}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default boolean generatedOnUpdate() {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,8 +13,6 @@ import org.hibernate.type.Type;
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import static org.hibernate.tuple.GenerationTiming.INSERT;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The counterpart of {@link IdentifierGenerator} for values generated by the database.
|
* The counterpart of {@link IdentifierGenerator} for values generated by the database.
|
||||||
* This interface is no longer the only way to handle database-generate identifiers.
|
* This interface is no longer the only way to handle database-generate identifiers.
|
||||||
|
@ -28,11 +26,19 @@ import static org.hibernate.tuple.GenerationTiming.INSERT;
|
||||||
public interface PostInsertIdentifierGenerator extends InDatabaseGenerator, Configurable {
|
public interface PostInsertIdentifierGenerator extends InDatabaseGenerator, Configurable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {@link GenerationTiming#INSERT}
|
* @return {@code true}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
default GenerationTiming getGenerationTiming() {
|
default boolean generatedOnInsert() {
|
||||||
return INSERT;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code false}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default boolean generatedOnUpdate() {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,7 +12,6 @@ import java.util.UUID;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.id.factory.spi.CustomIdGeneratorCreationContext;
|
import org.hibernate.id.factory.spi.CustomIdGeneratorCreationContext;
|
||||||
import org.hibernate.tuple.GenerationTiming;
|
|
||||||
import org.hibernate.tuple.InMemoryGenerator;
|
import org.hibernate.tuple.InMemoryGenerator;
|
||||||
import org.hibernate.type.descriptor.java.UUIDJavaType;
|
import org.hibernate.type.descriptor.java.UUIDJavaType;
|
||||||
import org.hibernate.type.descriptor.java.UUIDJavaType.ValueTransformer;
|
import org.hibernate.type.descriptor.java.UUIDJavaType.ValueTransformer;
|
||||||
|
@ -60,9 +59,20 @@ public class UuidGenerator implements InMemoryGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code true}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public GenerationTiming getGenerationTiming() {
|
public boolean generatedOnInsert() {
|
||||||
return GenerationTiming.INSERT;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code false}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean generatedOnUpdate() {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,22 +20,22 @@ import org.hibernate.tuple.InMemoryGenerator;
|
||||||
*/
|
*/
|
||||||
@Incubating
|
@Incubating
|
||||||
public interface GeneratedValueResolver {
|
public interface GeneratedValueResolver {
|
||||||
static GeneratedValueResolver from(
|
// static GeneratedValueResolver from(
|
||||||
Generator generator,
|
// Generator generator,
|
||||||
GenerationTiming requestedTiming,
|
// GenerationTiming requestedTiming,
|
||||||
int dbSelectionPosition) {
|
// int dbSelectionPosition) {
|
||||||
assert requestedTiming.isNotNever();
|
// assert requestedTiming.isNotNever();
|
||||||
|
//
|
||||||
|
// if ( generator == null || !generator.getGenerationTiming().includes( requestedTiming ) ) {
|
||||||
|
// return NoGeneratedValueResolver.INSTANCE;
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// return generator.generatedByDatabase()
|
||||||
|
// ? new InDatabaseGeneratedValueResolver( requestedTiming, dbSelectionPosition ) // in-db generation (column-default, function, etc)
|
||||||
|
// : new InMemoryGeneratedValueResolver( (InMemoryGenerator) generator, requestedTiming );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
if ( generator == null || !generator.getGenerationTiming().includes( requestedTiming ) ) {
|
// GenerationTiming getGenerationTiming();
|
||||||
return NoGeneratedValueResolver.INSTANCE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return generator.generatedByDatabase()
|
|
||||||
? new InDatabaseGeneratedValueResolver( requestedTiming, dbSelectionPosition ) // in-db generation (column-default, function, etc)
|
|
||||||
: new InMemoryGeneratedValueResolver( (InMemoryGenerator) generator, requestedTiming );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GenerationTiming getGenerationTiming();
|
|
||||||
Object resolveGeneratedValue(Object[] row, Object entity, SharedSessionContractImplementor session, Object currentValue);
|
Object resolveGeneratedValue(Object[] row, Object entity, SharedSessionContractImplementor session, Object currentValue);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,18 +18,18 @@ import org.hibernate.tuple.GenerationTiming;
|
||||||
*/
|
*/
|
||||||
@Internal
|
@Internal
|
||||||
public class InDatabaseGeneratedValueResolver implements GeneratedValueResolver {
|
public class InDatabaseGeneratedValueResolver implements GeneratedValueResolver {
|
||||||
private final GenerationTiming timing;
|
// private final GenerationTiming timing;
|
||||||
private final int resultPosition;
|
private final int resultPosition;
|
||||||
|
|
||||||
public InDatabaseGeneratedValueResolver(GenerationTiming timing, int resultPosition) {
|
public InDatabaseGeneratedValueResolver(GenerationTiming timing, int resultPosition) {
|
||||||
this.timing = timing;
|
// this.timing = timing;
|
||||||
this.resultPosition = resultPosition;
|
this.resultPosition = resultPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public GenerationTiming getGenerationTiming() {
|
// public GenerationTiming getGenerationTiming() {
|
||||||
return timing;
|
// return timing;
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object resolveGeneratedValue(Object[] row, Object entity, SharedSessionContractImplementor session, Object currentValue) {
|
public Object resolveGeneratedValue(Object[] row, Object entity, SharedSessionContractImplementor session, Object currentValue) {
|
||||||
|
|
|
@ -18,18 +18,18 @@ import org.hibernate.tuple.InMemoryGenerator;
|
||||||
*/
|
*/
|
||||||
@Internal
|
@Internal
|
||||||
public class InMemoryGeneratedValueResolver implements GeneratedValueResolver {
|
public class InMemoryGeneratedValueResolver implements GeneratedValueResolver {
|
||||||
private final GenerationTiming generationTiming;
|
// private final GenerationTiming generationTiming;
|
||||||
private final InMemoryGenerator valueGenerator;
|
private final InMemoryGenerator valueGenerator;
|
||||||
|
|
||||||
public InMemoryGeneratedValueResolver(InMemoryGenerator valueGenerator, GenerationTiming generationTiming) {
|
public InMemoryGeneratedValueResolver(InMemoryGenerator valueGenerator, GenerationTiming generationTiming) {
|
||||||
this.valueGenerator = valueGenerator;
|
this.valueGenerator = valueGenerator;
|
||||||
this.generationTiming = generationTiming;
|
// this.generationTiming = generationTiming;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public GenerationTiming getGenerationTiming() {
|
// public GenerationTiming getGenerationTiming() {
|
||||||
return generationTiming;
|
// return generationTiming;
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object resolveGeneratedValue(Object[] row, Object entity, SharedSessionContractImplementor session, Object currentValue) {
|
public Object resolveGeneratedValue(Object[] row, Object entity, SharedSessionContractImplementor session, Object currentValue) {
|
||||||
|
|
|
@ -11,8 +11,6 @@ import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.Incubating;
|
import org.hibernate.Incubating;
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
|
||||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
|
||||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
|
@ -25,7 +23,6 @@ import org.hibernate.metamodel.mapping.InDatabaseGeneratedValueResolver;
|
||||||
import org.hibernate.query.spi.QueryOptions;
|
import org.hibernate.query.spi.QueryOptions;
|
||||||
import org.hibernate.query.spi.QueryParameterBindings;
|
import org.hibernate.query.spi.QueryParameterBindings;
|
||||||
import org.hibernate.sql.ast.Clause;
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
|
||||||
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
||||||
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
||||||
|
@ -33,7 +30,6 @@ import org.hibernate.sql.exec.spi.Callback;
|
||||||
import org.hibernate.sql.exec.spi.ExecutionContext;
|
import org.hibernate.sql.exec.spi.ExecutionContext;
|
||||||
import org.hibernate.sql.exec.spi.JdbcOperationQuerySelect;
|
import org.hibernate.sql.exec.spi.JdbcOperationQuerySelect;
|
||||||
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
||||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
|
||||||
import org.hibernate.tuple.GenerationTiming;
|
import org.hibernate.tuple.GenerationTiming;
|
||||||
import org.hibernate.tuple.Generator;
|
import org.hibernate.tuple.Generator;
|
||||||
|
|
||||||
|
@ -100,7 +96,7 @@ public class GeneratedValuesProcessor {
|
||||||
final Generator generator = generators[ mapping.getStateArrayPosition() ];
|
final Generator generator = generators[ mapping.getStateArrayPosition() ];
|
||||||
if ( generator != null
|
if ( generator != null
|
||||||
&& generator.generatedByDatabase()
|
&& generator.generatedByDatabase()
|
||||||
&& generator.getGenerationTiming().isNotNever() ) {
|
&& generator.isNotNever() ) {
|
||||||
// this attribute is generated for the timing we are processing...
|
// this attribute is generated for the timing we are processing...
|
||||||
valueDescriptors.add( new GeneratedValueDescriptor(
|
valueDescriptors.add( new GeneratedValueDescriptor(
|
||||||
new InDatabaseGeneratedValueResolver( timing, generatedValuesToSelect.size() ),
|
new InDatabaseGeneratedValueResolver( timing, generatedValuesToSelect.size() ),
|
||||||
|
|
|
@ -20,10 +20,10 @@ public class NoGeneratedValueResolver implements GeneratedValueResolver {
|
||||||
*/
|
*/
|
||||||
public static final NoGeneratedValueResolver INSTANCE = new NoGeneratedValueResolver();
|
public static final NoGeneratedValueResolver INSTANCE = new NoGeneratedValueResolver();
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public GenerationTiming getGenerationTiming() {
|
// public GenerationTiming getGenerationTiming() {
|
||||||
return GenerationTiming.NEVER;
|
// return GenerationTiming.NEVER;
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object resolveGeneratedValue(Object[] row, Object entity, SharedSessionContractImplementor session, Object currentValue) {
|
public Object resolveGeneratedValue(Object[] row, Object entity, SharedSessionContractImplementor session, Object currentValue) {
|
||||||
|
|
|
@ -2773,7 +2773,7 @@ public abstract class AbstractEntityPersister
|
||||||
else {
|
else {
|
||||||
final Generator generator = attributeMapping.getGenerator();
|
final Generator generator = attributeMapping.getGenerator();
|
||||||
if ( generator!=null
|
if ( generator!=null
|
||||||
&& generator.getGenerationTiming().includesUpdate()
|
&& generator.generatedOnUpdate()
|
||||||
&& generator.generatedByDatabase() ) {
|
&& generator.generatedByDatabase() ) {
|
||||||
final InDatabaseGenerator databaseGenerator = (InDatabaseGenerator) generator;
|
final InDatabaseGenerator databaseGenerator = (InDatabaseGenerator) generator;
|
||||||
final Dialect dialect = getFactory().getJdbcServices().getDialect();
|
final Dialect dialect = getFactory().getJdbcServices().getDialect();
|
||||||
|
|
|
@ -106,7 +106,7 @@ public class InsertCoordinator extends AbstractMutationCoordinator {
|
||||||
Generator generator = generators[i];
|
Generator generator = generators[i];
|
||||||
if ( generator != null
|
if ( generator != null
|
||||||
&& !generator.generatedByDatabase()
|
&& !generator.generatedByDatabase()
|
||||||
&& generator.getGenerationTiming().includesInsert() ) {
|
&& generator.generatedOnInsert() ) {
|
||||||
values[i] = ( (InMemoryGenerator) generator ).generate( session, entity, values[i] );
|
values[i] = ( (InMemoryGenerator) generator ).generate( session, entity, values[i] );
|
||||||
entityPersister().setPropertyValue( entity, i, values[i] );
|
entityPersister().setPropertyValue( entity, i, values[i] );
|
||||||
}
|
}
|
||||||
|
@ -438,7 +438,7 @@ public class InsertCoordinator extends AbstractMutationCoordinator {
|
||||||
|
|
||||||
private static boolean isValueGenerationInSql(Generator generator, Dialect dialect) {
|
private static boolean isValueGenerationInSql(Generator generator, Dialect dialect) {
|
||||||
return generator != null
|
return generator != null
|
||||||
&& generator.getGenerationTiming().includesInsert()
|
&& generator.generatedOnInsert()
|
||||||
&& generator.generatedByDatabase()
|
&& generator.generatedByDatabase()
|
||||||
&& ( (InDatabaseGenerator) generator ).referenceColumnsInSql(dialect);
|
&& ( (InDatabaseGenerator) generator ).referenceColumnsInSql(dialect);
|
||||||
}
|
}
|
||||||
|
|
|
@ -337,14 +337,14 @@ public class UpdateCoordinatorStandard extends AbstractMutationCoordinator imple
|
||||||
|
|
||||||
private boolean isValueGenerationInSql(Generator generator, Dialect dialect) {
|
private boolean isValueGenerationInSql(Generator generator, Dialect dialect) {
|
||||||
return generator != null
|
return generator != null
|
||||||
&& generator.getGenerationTiming().includesUpdate()
|
&& generator.generatedOnUpdate()
|
||||||
&& generator.generatedByDatabase()
|
&& generator.generatedByDatabase()
|
||||||
&& ((InDatabaseGenerator) generator).referenceColumnsInSql(dialect);
|
&& ((InDatabaseGenerator) generator).referenceColumnsInSql(dialect);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isValueGenerationInSqlNoWrite(Generator generator, Dialect dialect) {
|
private boolean isValueGenerationInSqlNoWrite(Generator generator, Dialect dialect) {
|
||||||
return generator != null
|
return generator != null
|
||||||
&& generator.getGenerationTiming().includesUpdate()
|
&& generator.generatedOnUpdate()
|
||||||
&& generator.generatedByDatabase()
|
&& generator.generatedByDatabase()
|
||||||
&& ((InDatabaseGenerator) generator).referenceColumnsInSql(dialect)
|
&& ((InDatabaseGenerator) generator).referenceColumnsInSql(dialect)
|
||||||
&& !((InDatabaseGenerator) generator).writePropertyValue();
|
&& !((InDatabaseGenerator) generator).writePropertyValue();
|
||||||
|
@ -451,7 +451,7 @@ public class UpdateCoordinatorStandard extends AbstractMutationCoordinator imple
|
||||||
Generator generator = generators[i];
|
Generator generator = generators[i];
|
||||||
if ( generator != null
|
if ( generator != null
|
||||||
&& !generator.generatedByDatabase()
|
&& !generator.generatedByDatabase()
|
||||||
&& generator.getGenerationTiming().includesUpdate() ) {
|
&& generator.generatedOnUpdate() ) {
|
||||||
newValues[i] = ( (InMemoryGenerator) generator ).generate( session, object, newValues[i] );
|
newValues[i] = ( (InMemoryGenerator) generator ).generate( session, object, newValues[i] );
|
||||||
entityPersister().setPropertyValue( object, i, newValues[i] );
|
entityPersister().setPropertyValue( object, i, newValues[i] );
|
||||||
fieldsPreUpdateNeeded[count++] = i;
|
fieldsPreUpdateNeeded[count++] = i;
|
||||||
|
|
|
@ -20,8 +20,13 @@ public class GeneratedAlwaysValueGeneration
|
||||||
public GeneratedAlwaysValueGeneration() {}
|
public GeneratedAlwaysValueGeneration() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GenerationTiming getGenerationTiming() {
|
public boolean generatedOnUpdate() {
|
||||||
return GenerationTiming.ALWAYS;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean generatedOnInsert() {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -9,8 +9,6 @@ package org.hibernate.tuple;
|
||||||
import org.hibernate.annotations.Generated;
|
import org.hibernate.annotations.Generated;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
|
|
||||||
import java.lang.reflect.Member;
|
|
||||||
|
|
||||||
import static org.hibernate.internal.util.StringHelper.isEmpty;
|
import static org.hibernate.internal.util.StringHelper.isEmpty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,8 +39,13 @@ public class GeneratedValueGeneration implements InDatabaseGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GenerationTiming getGenerationTiming() {
|
public boolean generatedOnInsert() {
|
||||||
return timing;
|
return timing.includesInsert();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean generatedOnUpdate() {
|
||||||
|
return timing.includesUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -48,19 +48,6 @@ import java.io.Serializable;
|
||||||
* @since 6.2
|
* @since 6.2
|
||||||
*/
|
*/
|
||||||
public interface Generator extends Serializable {
|
public interface Generator extends Serializable {
|
||||||
/**
|
|
||||||
* Specifies that the property value is generated:
|
|
||||||
* <ul>
|
|
||||||
* <li>{@linkplain GenerationTiming#INSERT when the entity is inserted},
|
|
||||||
* <li>{@linkplain GenerationTiming#UPDATE when the entity is updated},
|
|
||||||
* <li>{@linkplain GenerationTiming#ALWAYS whenever the entity is inserted or updated}, or
|
|
||||||
* <li>{@linkplain GenerationTiming#NEVER never}.
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* @return The {@link GenerationTiming} specifying when the value is generated.
|
|
||||||
*/
|
|
||||||
GenerationTiming getGenerationTiming();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if the property value is generated in Java, or by the database.
|
* Determines if the property value is generated in Java, or by the database.
|
||||||
*
|
*
|
||||||
|
@ -68,4 +55,12 @@ public interface Generator extends Serializable {
|
||||||
* generated in Java using a {@link ValueGenerator}.
|
* generated in Java using a {@link ValueGenerator}.
|
||||||
*/
|
*/
|
||||||
boolean generatedByDatabase();
|
boolean generatedByDatabase();
|
||||||
|
|
||||||
|
boolean generatedOnInsert();
|
||||||
|
|
||||||
|
boolean generatedOnUpdate();
|
||||||
|
|
||||||
|
default boolean isNotNever() {
|
||||||
|
return generatedOnInsert() || generatedOnUpdate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ import java.sql.SQLException;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
|
|
||||||
import static java.sql.Types.TIMESTAMP;
|
import static java.sql.Types.TIMESTAMP;
|
||||||
import static org.hibernate.tuple.GenerationTiming.ALWAYS;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Value generation strategy using the query {@link Dialect#getCurrentTimestampSelectString()}.
|
* Value generation strategy using the query {@link Dialect#getCurrentTimestampSelectString()}.
|
||||||
|
@ -68,9 +67,20 @@ public class SourceGeneration implements InMemoryGenerator, ValueGenerator<Objec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code true}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public GenerationTiming getGenerationTiming() {
|
public boolean generatedOnInsert() {
|
||||||
return ALWAYS;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code false}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean generatedOnUpdate() {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -35,9 +35,20 @@ public class TenantIdGeneration implements InMemoryGenerator {
|
||||||
propertyType = getPropertyType( member );
|
propertyType = getPropertyType( member );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code true}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public GenerationTiming getGenerationTiming() {
|
public boolean generatedOnInsert() {
|
||||||
return GenerationTiming.INSERT;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code false}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean generatedOnUpdate() {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -22,6 +22,29 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
* @see AnnotationValueGeneration
|
* @see AnnotationValueGeneration
|
||||||
*/
|
*/
|
||||||
public interface ValueGeneration extends InMemoryGenerator, InDatabaseGenerator {
|
public interface ValueGeneration extends InMemoryGenerator, InDatabaseGenerator {
|
||||||
|
/**
|
||||||
|
* Specifies that the property value is generated:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@linkplain GenerationTiming#INSERT when the entity is inserted},
|
||||||
|
* <li>{@linkplain GenerationTiming#UPDATE when the entity is updated},
|
||||||
|
* <li>{@linkplain GenerationTiming#ALWAYS whenever the entity is inserted or updated}, or
|
||||||
|
* <li>{@linkplain GenerationTiming#NEVER never}.
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @return The {@link GenerationTiming} specifying when the value is generated.
|
||||||
|
*/
|
||||||
|
GenerationTiming getGenerationTiming();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default boolean generatedOnInsert() {
|
||||||
|
return getGenerationTiming().includesInsert();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default boolean generatedOnUpdate() {
|
||||||
|
return getGenerationTiming().includesUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain the {@linkplain ValueGenerator Java value generator}, if the value is generated in
|
* Obtain the {@linkplain ValueGenerator Java value generator}, if the value is generated in
|
||||||
* Java, or return {@code null} if the value is generated by the database.
|
* Java, or return {@code null} if the value is generated by the database.
|
||||||
|
|
|
@ -44,11 +44,23 @@ public class VmValueGeneration implements InMemoryGenerator {
|
||||||
: annotation.timing();
|
: annotation.timing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code true}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public GenerationTiming getGenerationTiming() {
|
public boolean generatedOnInsert() {
|
||||||
return generationTiming;
|
return generationTiming.includesInsert();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code false}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean generatedOnUpdate() {
|
||||||
|
return generationTiming.includesUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object generate(SharedSessionContractImplementor session, Object owner, Object currentValue) {
|
public Object generate(SharedSessionContractImplementor session, Object owner, Object currentValue) {
|
||||||
return generator.generateValue( (Session) session, owner, currentValue );
|
return generator.generateValue( (Session) session, owner, currentValue );
|
||||||
|
|
|
@ -42,7 +42,6 @@ import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.persister.spi.PersisterCreationContext;
|
import org.hibernate.persister.spi.PersisterCreationContext;
|
||||||
import org.hibernate.tuple.GenerationTiming;
|
|
||||||
import org.hibernate.tuple.Generator;
|
import org.hibernate.tuple.Generator;
|
||||||
import org.hibernate.tuple.IdentifierProperty;
|
import org.hibernate.tuple.IdentifierProperty;
|
||||||
import org.hibernate.tuple.InDatabaseGenerator;
|
import org.hibernate.tuple.InDatabaseGenerator;
|
||||||
|
@ -310,34 +309,21 @@ public class EntityMetamodel implements Serializable {
|
||||||
propertyInsertability[i] = false;
|
propertyInsertability[i] = false;
|
||||||
propertyUpdateability[i] = false;
|
propertyUpdateability[i] = false;
|
||||||
}
|
}
|
||||||
// we have some level of generation indicated
|
if ( generator.generatedOnInsert() ) {
|
||||||
switch ( generator.getGenerationTiming() ) {
|
|
||||||
case INSERT:
|
|
||||||
if ( generator.generatedByDatabase() ) {
|
if ( generator.generatedByDatabase() ) {
|
||||||
foundPostInsertGeneratedValues = true;
|
foundPostInsertGeneratedValues = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
foundPreInsertGeneratedValues = true;
|
foundPreInsertGeneratedValues = true;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case UPDATE:
|
if ( generator.generatedOnUpdate() ) {
|
||||||
if ( generator.generatedByDatabase() ) {
|
if ( generator.generatedByDatabase() ) {
|
||||||
foundPostUpdateGeneratedValues = true;
|
foundPostUpdateGeneratedValues = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
foundPreUpdateGeneratedValues = true;
|
foundPreUpdateGeneratedValues = true;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case ALWAYS:
|
|
||||||
if ( generator.generatedByDatabase() ) {
|
|
||||||
foundPostInsertGeneratedValues = true;
|
|
||||||
foundPostUpdateGeneratedValues = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
foundPreInsertGeneratedValues = true;
|
|
||||||
foundPreUpdateGeneratedValues = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,7 +454,7 @@ public class EntityMetamodel implements Serializable {
|
||||||
final GeneratorCreator generatorCreator = mappingProperty.getValueGeneratorCreator();
|
final GeneratorCreator generatorCreator = mappingProperty.getValueGeneratorCreator();
|
||||||
if ( generatorCreator != null ) {
|
if ( generatorCreator != null ) {
|
||||||
final Generator generator = mappingProperty.createGenerator( context );
|
final Generator generator = mappingProperty.createGenerator( context );
|
||||||
if ( generator.getGenerationTiming().isNotNever() ) {
|
if ( generator.isNotNever() ) {
|
||||||
return generator;
|
return generator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -524,7 +510,7 @@ public class EntityMetamodel implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void add(InMemoryGenerator inMemoryStrategy) {
|
private void add(InMemoryGenerator inMemoryStrategy) {
|
||||||
if ( inMemoryStrategy.getGenerationTiming().isNotNever() ) {
|
if ( inMemoryStrategy.isNotNever() ) {
|
||||||
hadInMemoryGeneration = true;
|
hadInMemoryGeneration = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -535,7 +521,7 @@ public class EntityMetamodel implements Serializable {
|
||||||
}
|
}
|
||||||
inDatabaseStrategies.add( inDatabaseStrategy );
|
inDatabaseStrategies.add( inDatabaseStrategy );
|
||||||
|
|
||||||
if ( inDatabaseStrategy.getGenerationTiming().isNotNever() ) {
|
if ( inDatabaseStrategy.isNotNever() ) {
|
||||||
hadInDatabaseGeneration = true;
|
hadInDatabaseGeneration = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -563,7 +549,8 @@ public class EntityMetamodel implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
// the base-line values for the aggregated InDatabaseValueGenerationStrategy we will build here.
|
// the base-line values for the aggregated InDatabaseValueGenerationStrategy we will build here.
|
||||||
GenerationTiming timing = GenerationTiming.NEVER;
|
boolean generatedOnInsert = false;
|
||||||
|
boolean generatedOnUpdate = false;
|
||||||
boolean referenceColumns = false;
|
boolean referenceColumns = false;
|
||||||
String[] columnValues = new String[ composite.getColumnSpan() ];
|
String[] columnValues = new String[ composite.getColumnSpan() ];
|
||||||
|
|
||||||
|
@ -573,29 +560,8 @@ public class EntityMetamodel implements Serializable {
|
||||||
for ( Property property : composite.getProperties() ) {
|
for ( Property property : composite.getProperties() ) {
|
||||||
propertyIndex++;
|
propertyIndex++;
|
||||||
final InDatabaseGenerator subStrategy = inDatabaseStrategies.get( propertyIndex );
|
final InDatabaseGenerator subStrategy = inDatabaseStrategies.get( propertyIndex );
|
||||||
switch ( subStrategy.getGenerationTiming() ) {
|
generatedOnUpdate = generatedOnUpdate || subStrategy.generatedOnUpdate();
|
||||||
case INSERT:
|
generatedOnInsert = generatedOnInsert || subStrategy.generatedOnInsert();
|
||||||
switch ( timing ) {
|
|
||||||
case UPDATE:
|
|
||||||
timing = GenerationTiming.ALWAYS;
|
|
||||||
break;
|
|
||||||
case NEVER:
|
|
||||||
timing = GenerationTiming.INSERT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case UPDATE:
|
|
||||||
switch ( timing ) {
|
|
||||||
case INSERT:
|
|
||||||
timing = GenerationTiming.ALWAYS;
|
|
||||||
break;
|
|
||||||
case NEVER:
|
|
||||||
timing = GenerationTiming.UPDATE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ALWAYS:
|
|
||||||
timing = GenerationTiming.ALWAYS;
|
|
||||||
}
|
|
||||||
if ( subStrategy.referenceColumnsInSql(dialect) ) {
|
if ( subStrategy.referenceColumnsInSql(dialect) ) {
|
||||||
// override base-line value
|
// override base-line value
|
||||||
referenceColumns = true;
|
referenceColumns = true;
|
||||||
|
@ -619,13 +585,17 @@ public class EntityMetamodel implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
// then use the aggregated values to build the InDatabaseValueGenerationStrategy
|
// then use the aggregated values to build the InDatabaseValueGenerationStrategy
|
||||||
return new InDatabaseGeneratorImpl( timing, referenceColumns, columnValues );
|
return new InDatabaseGeneratorImpl( generatedOnUpdate, generatedOnInsert, referenceColumns, columnValues );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return new Generator() {
|
return new Generator() {
|
||||||
@Override
|
@Override
|
||||||
public GenerationTiming getGenerationTiming() {
|
public boolean generatedOnInsert() {
|
||||||
return GenerationTiming.NEVER;
|
return false;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean generatedOnUpdate() {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public boolean generatedByDatabase() {
|
public boolean generatedByDatabase() {
|
||||||
|
@ -637,22 +607,30 @@ public class EntityMetamodel implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class InDatabaseGeneratorImpl implements InDatabaseGenerator {
|
private static class InDatabaseGeneratorImpl implements InDatabaseGenerator {
|
||||||
private final GenerationTiming timing;
|
private final boolean generatedOnUpdate;
|
||||||
|
private final boolean generatedOnInsert;
|
||||||
private final boolean referenceColumnInSql;
|
private final boolean referenceColumnInSql;
|
||||||
private final String[] referencedColumnValues;
|
private final String[] referencedColumnValues;
|
||||||
|
|
||||||
private InDatabaseGeneratorImpl(
|
private InDatabaseGeneratorImpl(
|
||||||
GenerationTiming timing,
|
boolean generatedOnUpdate,
|
||||||
|
boolean generatedOnInsert,
|
||||||
boolean referenceColumnInSql,
|
boolean referenceColumnInSql,
|
||||||
String[] referencedColumnValues) {
|
String[] referencedColumnValues) {
|
||||||
this.timing = timing;
|
this.generatedOnUpdate = generatedOnUpdate;
|
||||||
|
this.generatedOnInsert = generatedOnInsert;
|
||||||
this.referenceColumnInSql = referenceColumnInSql;
|
this.referenceColumnInSql = referenceColumnInSql;
|
||||||
this.referencedColumnValues = referencedColumnValues;
|
this.referencedColumnValues = referencedColumnValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GenerationTiming getGenerationTiming() {
|
public boolean generatedOnInsert() {
|
||||||
return timing;
|
return generatedOnInsert;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean generatedOnUpdate() {
|
||||||
|
return generatedOnUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -694,17 +672,17 @@ public class EntityMetamodel implements Serializable {
|
||||||
// * That code checks that there is a natural identifier before making this call, so we assume the same here
|
// * That code checks that there is a natural identifier before making this call, so we assume the same here
|
||||||
// * That code assumes a non-composite natural-id, so we assume the same here
|
// * That code assumes a non-composite natural-id, so we assume the same here
|
||||||
final Generator strategy = generators[ naturalIdPropertyNumbers[0] ];
|
final Generator strategy = generators[ naturalIdPropertyNumbers[0] ];
|
||||||
return strategy != null && strategy.getGenerationTiming().isNotNever();
|
return strategy != null && strategy.isNotNever();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isVersionGeneratedByDatabase() {
|
public boolean isVersionGeneratedByDatabase() {
|
||||||
final Generator strategy = generators[ versionPropertyIndex ];
|
final Generator strategy = generators[ versionPropertyIndex ];
|
||||||
return strategy != null && strategy.getGenerationTiming().isNotNever() && strategy.generatedByDatabase();
|
return strategy != null && strategy.isNotNever() && strategy.generatedByDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isVersionGeneratedInMemory() {
|
public boolean isVersionGeneratedInMemory() {
|
||||||
final Generator strategy = generators[ versionPropertyIndex ];
|
final Generator strategy = generators[ versionPropertyIndex ];
|
||||||
return strategy != null && strategy.getGenerationTiming().isNotNever() && !strategy.generatedByDatabase();
|
return strategy != null && strategy.isNotNever() && !strategy.generatedByDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getNaturalIdentifierProperties() {
|
public int[] getNaturalIdentifierProperties() {
|
||||||
|
|
|
@ -91,8 +91,13 @@ public class GeneratedUuidTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GenerationTiming getGenerationTiming() {
|
public boolean generatedOnInsert() {
|
||||||
return timing;
|
return timing.includesInsert();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean generatedOnUpdate() {
|
||||||
|
return timing.includesUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -123,7 +123,7 @@ public final class AuditMetadataGenerator extends AbstractMetadataGenerator {
|
||||||
final GeneratorCreator generation = property.getValueGeneratorCreator();
|
final GeneratorCreator generation = property.getValueGeneratorCreator();
|
||||||
if ( generation instanceof GeneratedValueGeneration ) {
|
if ( generation instanceof GeneratedValueGeneration ) {
|
||||||
final GeneratedValueGeneration valueGeneration = (GeneratedValueGeneration) generation;
|
final GeneratedValueGeneration valueGeneration = (GeneratedValueGeneration) generation;
|
||||||
if ( valueGeneration.getGenerationTiming().includesInsert() ) {
|
if ( valueGeneration.generatedOnInsert() ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue