HHH-15789 allow any InMemoryGenerator to generate ids
This commit is contained in:
parent
7f72696fff
commit
26e7393775
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.annotations;
|
||||
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
|
||||
import java.lang.annotation.Repeatable;
|
||||
import java.lang.annotation.Retention;
|
||||
|
@ -74,12 +74,11 @@ public @interface GenericGenerator {
|
|||
*/
|
||||
String name();
|
||||
/**
|
||||
* The type of identifier generator, a class implementing
|
||||
* {@link org.hibernate.id.IdentifierGenerator}.
|
||||
* The type of identifier generator, a class implementing {@link InMemoryGenerator}.
|
||||
*
|
||||
* @since 6.2
|
||||
*/
|
||||
Class<? extends IdentifierGenerator> type() default IdentifierGenerator.class;
|
||||
Class<? extends InMemoryGenerator> type() default InMemoryGenerator.class;
|
||||
/**
|
||||
* The type of identifier generator, the name of either:
|
||||
* <ul>
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.lang.annotation.RetentionPolicy;
|
|||
import java.lang.annotation.Target;
|
||||
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
|
||||
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
@ -63,8 +64,8 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|||
@Retention(RUNTIME)
|
||||
public @interface IdGeneratorType {
|
||||
/**
|
||||
* A class that implements {@link IdentifierGenerator} and has a
|
||||
* constructor with the signature:
|
||||
* A class that implements {@link InMemoryGenerator} and has a constructor
|
||||
* with the signature:
|
||||
* <pre>{@code
|
||||
* public GeneratorType(AnnotationType config, Member idMember,
|
||||
* CustomIdGeneratorCreationContext creationContext)
|
||||
|
@ -73,5 +74,5 @@ public @interface IdGeneratorType {
|
|||
* {@code IdentifierGenerator}, and {@code AnnotationType} is the
|
||||
* annotation type to which this annotation was applied.
|
||||
*/
|
||||
Class<? extends IdentifierGenerator> value();
|
||||
Class<? extends InMemoryGenerator> value();
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ import org.hibernate.boot.model.naming.ImplicitIndexNameSource;
|
|||
import org.hibernate.boot.model.naming.ImplicitUniqueKeyNameSource;
|
||||
import org.hibernate.boot.model.relational.AuxiliaryDatabaseObject;
|
||||
import org.hibernate.boot.model.relational.Database;
|
||||
import org.hibernate.boot.model.relational.ExportableProducer;
|
||||
import org.hibernate.boot.model.relational.Namespace;
|
||||
import org.hibernate.boot.model.relational.QualifiedTableName;
|
||||
import org.hibernate.boot.model.source.internal.ImplicitColumnNamingSecondPass;
|
||||
|
@ -102,6 +103,7 @@ import org.hibernate.metamodel.CollectionClassification;
|
|||
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
|
||||
import org.hibernate.query.named.NamedObjectRepository;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
@ -2314,13 +2316,15 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
|
|||
// It was done this way in the old code too, so no "regression" here; but
|
||||
// it could be done better
|
||||
try {
|
||||
final IdentifierGenerator ig = identifierValueBinding.createIdentifierGenerator(
|
||||
final InMemoryGenerator generator = identifierValueBinding.createIdentifierGenerator(
|
||||
bootstrapContext.getIdentifierGeneratorFactory(),
|
||||
dialect,
|
||||
entityBinding
|
||||
);
|
||||
|
||||
ig.registerExportables( getDatabase() );
|
||||
if ( generator instanceof ExportableProducer ) {
|
||||
( (ExportableProducer) generator ).registerExportables( getDatabase() );
|
||||
}
|
||||
}
|
||||
catch (MappingException e) {
|
||||
// ignore this for now. The reasoning being "non-reflective" binding as needed
|
||||
|
|
|
@ -7,10 +7,20 @@
|
|||
package org.hibernate.boot.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Index;
|
||||
import jakarta.persistence.SequenceGenerator;
|
||||
import jakarta.persistence.TableGenerator;
|
||||
import jakarta.persistence.UniqueConstraint;
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.Internal;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
|
@ -74,6 +84,171 @@ public class IdentifierGeneratorDefinition implements Serializable {
|
|||
return parameters;
|
||||
}
|
||||
|
||||
@Internal
|
||||
public static IdentifierGeneratorDefinition createImplicit(
|
||||
String name,
|
||||
Class<?> idType,
|
||||
String generatorName,
|
||||
IdGeneratorStrategyInterpreter generationInterpreter,
|
||||
GenerationType generationType) {
|
||||
// If we were unable to locate an actual matching named generator assume
|
||||
// a sequence/table of the given name, make one based on GenerationType.
|
||||
|
||||
if ( generationType == null) {
|
||||
return buildSequenceGeneratorDefinition( name, generationInterpreter );
|
||||
}
|
||||
|
||||
final String strategyName;
|
||||
switch ( generationType ) {
|
||||
case SEQUENCE:
|
||||
return buildSequenceGeneratorDefinition( name, generationInterpreter );
|
||||
case TABLE:
|
||||
return buildTableGeneratorDefinition( name, generationInterpreter );
|
||||
// really AUTO and IDENTITY work the same in this respect, aside from the actual strategy name
|
||||
case IDENTITY:
|
||||
strategyName = "identity";
|
||||
break;
|
||||
case AUTO:
|
||||
strategyName = generationInterpreter.determineGeneratorName(
|
||||
generationType,
|
||||
new IdGeneratorStrategyInterpreter.GeneratorNameDeterminationContext() {
|
||||
@Override
|
||||
public Class<?> getIdType() {
|
||||
return idType;
|
||||
}
|
||||
@Override
|
||||
public String getGeneratedValueGeneratorName() {
|
||||
return generatorName;
|
||||
}
|
||||
}
|
||||
);
|
||||
break;
|
||||
default:
|
||||
throw new AssertionFailure( "unknown generator type: " + generationType );
|
||||
}
|
||||
|
||||
return new IdentifierGeneratorDefinition(
|
||||
name,
|
||||
strategyName,
|
||||
Collections.singletonMap( IdentifierGenerator.GENERATOR_NAME, name )
|
||||
);
|
||||
}
|
||||
|
||||
private static IdentifierGeneratorDefinition buildTableGeneratorDefinition(String name, IdGeneratorStrategyInterpreter generationInterpreter) {
|
||||
final Builder builder = new Builder();
|
||||
generationInterpreter.interpretTableGenerator(
|
||||
new TableGenerator() {
|
||||
@Override
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String table() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int initialValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int allocationSize() {
|
||||
return 50;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String catalog() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String schema() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String pkColumnName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String valueColumnName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String pkColumnValue() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public UniqueConstraint[] uniqueConstraints() {
|
||||
return new UniqueConstraint[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Index[] indexes() {
|
||||
return new Index[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Annotation> annotationType() {
|
||||
return TableGenerator.class;
|
||||
}
|
||||
},
|
||||
builder
|
||||
);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static IdentifierGeneratorDefinition buildSequenceGeneratorDefinition(String name, IdGeneratorStrategyInterpreter generationInterpreter) {
|
||||
final Builder builder = new Builder();
|
||||
generationInterpreter.interpretSequenceGenerator(
|
||||
new SequenceGenerator() {
|
||||
@Override
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String sequenceName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String catalog() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String schema() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int initialValue() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int allocationSize() {
|
||||
return 50;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Annotation> annotationType() {
|
||||
return SequenceGenerator.class;
|
||||
}
|
||||
},
|
||||
builder
|
||||
);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if ( this == o ) {
|
||||
|
|
|
@ -53,6 +53,7 @@ import org.hibernate.annotations.ParamDef;
|
|||
import org.hibernate.annotations.Parameter;
|
||||
import org.hibernate.annotations.Parent;
|
||||
import org.hibernate.annotations.TimeZoneStorage;
|
||||
import org.hibernate.annotations.ValueGenerationType;
|
||||
import org.hibernate.annotations.common.reflection.ReflectionManager;
|
||||
import org.hibernate.annotations.common.reflection.XAnnotatedElement;
|
||||
import org.hibernate.annotations.common.reflection.XClass;
|
||||
|
@ -91,6 +92,7 @@ import org.hibernate.property.access.internal.PropertyAccessStrategyMixedImpl;
|
|||
import org.hibernate.property.access.spi.PropertyAccessStrategy;
|
||||
import org.hibernate.resource.beans.spi.ManagedBean;
|
||||
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.CustomType;
|
||||
import org.hibernate.type.descriptor.java.BasicJavaType;
|
||||
|
@ -152,6 +154,7 @@ import static org.hibernate.cfg.InheritanceState.getInheritanceStateOfSuperEntit
|
|||
import static org.hibernate.cfg.InheritanceState.getSuperclassInheritanceState;
|
||||
import static org.hibernate.cfg.PropertyHolderBuilder.buildPropertyHolder;
|
||||
import static org.hibernate.cfg.annotations.HCANNHelper.findContainingAnnotation;
|
||||
import static org.hibernate.cfg.annotations.PropertyBinder.generatorCreator;
|
||||
import static org.hibernate.cfg.annotations.PropertyBinder.identifierGeneratorCreator;
|
||||
import static org.hibernate.internal.CoreLogging.messageLogger;
|
||||
import static org.hibernate.mapping.Constraint.hashedName;
|
||||
|
@ -477,10 +480,10 @@ public final class AnnotationBinder {
|
|||
else if ( generatorAnnotation instanceof GenericGenerator ) {
|
||||
final GenericGenerator genericGenerator = (GenericGenerator) generatorAnnotation;
|
||||
definitionBuilder.setName( genericGenerator.name() );
|
||||
final String strategy = genericGenerator.type().equals(IdentifierGenerator.class)
|
||||
final String strategy = genericGenerator.type().equals(InMemoryGenerator.class)
|
||||
? genericGenerator.strategy()
|
||||
: genericGenerator.type().getName();
|
||||
definitionBuilder.setStrategy(strategy);
|
||||
definitionBuilder.setStrategy( strategy );
|
||||
for ( Parameter parameter : genericGenerator.parameters() ) {
|
||||
definitionBuilder.addParam( parameter.name(), parameter.value() );
|
||||
}
|
||||
|
@ -1806,9 +1809,14 @@ public final class AnnotationBinder {
|
|||
+ "' belongs to an '@IdClass' and may not be annotated '@Id' or '@EmbeddedId'" );
|
||||
}
|
||||
final XProperty idProperty = inferredData.getProperty();
|
||||
final Annotation generatorAnnotation = findContainingAnnotation( idProperty, IdGeneratorType.class );
|
||||
if ( generatorAnnotation != null ) {
|
||||
idValue.setCustomIdGeneratorCreator( identifierGeneratorCreator( idProperty, generatorAnnotation ) );
|
||||
final Annotation idGeneratorAnnotation = findContainingAnnotation( idProperty, IdGeneratorType.class );
|
||||
final Annotation generatorAnnotation = findContainingAnnotation( idProperty, ValueGenerationType.class );
|
||||
//TODO: validate that we don't have too many generator annotations and throw
|
||||
if ( idGeneratorAnnotation != null ) {
|
||||
idValue.setCustomIdGeneratorCreator( identifierGeneratorCreator( idProperty, idGeneratorAnnotation ) );
|
||||
}
|
||||
else if ( generatorAnnotation != null ) {
|
||||
idValue.setCustomGeneratorCreator( generatorCreator( idProperty, generatorAnnotation ) );
|
||||
}
|
||||
else {
|
||||
final XClass entityClass = inferredData.getClassOrElement();
|
||||
|
|
|
@ -11,7 +11,6 @@ import java.lang.annotation.Repeatable;
|
|||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
@ -41,8 +40,6 @@ import org.hibernate.annotations.SqlFragmentAlias;
|
|||
import org.hibernate.annotations.common.reflection.XAnnotatedElement;
|
||||
import org.hibernate.annotations.common.reflection.XClass;
|
||||
import org.hibernate.annotations.common.reflection.XProperty;
|
||||
import org.hibernate.boot.model.IdGeneratorStrategyInterpreter;
|
||||
import org.hibernate.boot.model.IdGeneratorStrategyInterpreter.GeneratorNameDeterminationContext;
|
||||
import org.hibernate.boot.model.IdentifierGeneratorDefinition;
|
||||
import org.hibernate.boot.spi.InFlightMetadataCollector;
|
||||
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||
|
@ -74,10 +71,6 @@ import org.jboss.logging.Logger;
|
|||
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Index;
|
||||
import jakarta.persistence.SequenceGenerator;
|
||||
import jakarta.persistence.TableGenerator;
|
||||
import jakarta.persistence.UniqueConstraint;
|
||||
|
||||
import static org.hibernate.cfg.AnnotatedColumn.buildColumnOrFormulaFromAnnotation;
|
||||
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
|
||||
|
@ -777,7 +770,7 @@ public class BinderHelper {
|
|||
|
||||
if ( !isEmptyAnnotationValue( generatorName ) ) {
|
||||
//we have a named generator
|
||||
final IdentifierGeneratorDefinition definition = getIdentifierGenerator(
|
||||
final IdentifierGeneratorDefinition definition = makeIdentifierGeneratorDefinition(
|
||||
generatorName,
|
||||
property,
|
||||
localGenerators,
|
||||
|
@ -823,7 +816,7 @@ public class BinderHelper {
|
|||
makeIdGenerator( id, idXProperty, generatorType, generatorName, buildingContext, localIdentifiers );
|
||||
}
|
||||
|
||||
private static IdentifierGeneratorDefinition getIdentifierGenerator(
|
||||
private static IdentifierGeneratorDefinition makeIdentifierGeneratorDefinition(
|
||||
String name,
|
||||
XProperty idXProperty,
|
||||
Map<String, IdentifierGeneratorDefinition> localGenerators,
|
||||
|
@ -843,174 +836,21 @@ public class BinderHelper {
|
|||
|
||||
log.debugf( "Could not resolve explicit IdentifierGeneratorDefinition - using implicit interpretation (%s)", name );
|
||||
|
||||
// If we were unable to locate an actual matching named generator assume a sequence/table of the given name.
|
||||
// this really needs access to the `jakarta.persistence.GenerationType` to work completely properly
|
||||
//
|
||||
// (the crux of HHH-12122)
|
||||
|
||||
// temporarily, in lieu of having access to GenerationType, assume the EnhancedSequenceGenerator
|
||||
// for the purpose of testing the feasibility of the approach
|
||||
|
||||
final GeneratedValue generatedValueAnn = idXProperty.getAnnotation( GeneratedValue.class );
|
||||
if ( generatedValueAnn == null ) {
|
||||
final GeneratedValue generatedValue = idXProperty.getAnnotation( GeneratedValue.class );
|
||||
if ( generatedValue == null ) {
|
||||
// this should really never happen, but it's easy to protect against it...
|
||||
return new IdentifierGeneratorDefinition( "assigned", "assigned" );
|
||||
}
|
||||
|
||||
final IdGeneratorStrategyInterpreter generationInterpreter =
|
||||
buildingContext.getBuildingOptions().getIdGenerationTypeInterpreter();
|
||||
|
||||
final GenerationType generationType = interpretGenerationType( generatedValueAnn );
|
||||
|
||||
if ( generationType == null || generationType == GenerationType.SEQUENCE ) {
|
||||
// NOTE : `null` will ultimately be interpreted as "hibernate_sequence"
|
||||
log.debugf( "Building implicit sequence-based IdentifierGeneratorDefinition (%s)", name );
|
||||
final IdentifierGeneratorDefinition.Builder builder = new IdentifierGeneratorDefinition.Builder();
|
||||
generationInterpreter.interpretSequenceGenerator(
|
||||
new SequenceGenerator() {
|
||||
@Override
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String sequenceName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String catalog() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String schema() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int initialValue() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int allocationSize() {
|
||||
return 50;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Annotation> annotationType() {
|
||||
return SequenceGenerator.class;
|
||||
}
|
||||
},
|
||||
builder
|
||||
);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
else if ( generationType == GenerationType.TABLE ) {
|
||||
// NOTE : `null` will ultimately be interpreted as "hibernate_sequence"
|
||||
log.debugf( "Building implicit table-based IdentifierGeneratorDefinition (%s)", name );
|
||||
final IdentifierGeneratorDefinition.Builder builder = new IdentifierGeneratorDefinition.Builder();
|
||||
generationInterpreter.interpretTableGenerator(
|
||||
new TableGenerator() {
|
||||
@Override
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String table() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int initialValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int allocationSize() {
|
||||
return 50;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String catalog() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String schema() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String pkColumnName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String valueColumnName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String pkColumnValue() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public UniqueConstraint[] uniqueConstraints() {
|
||||
return new UniqueConstraint[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Index[] indexes() {
|
||||
return new Index[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Annotation> annotationType() {
|
||||
return TableGenerator.class;
|
||||
}
|
||||
},
|
||||
builder
|
||||
);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
// really AUTO and IDENTITY work the same in this respect, aside from the actual strategy name
|
||||
final String strategyName;
|
||||
if ( generationType == GenerationType.IDENTITY ) {
|
||||
strategyName = "identity";
|
||||
}
|
||||
else {
|
||||
strategyName = generationInterpreter.determineGeneratorName(
|
||||
generationType,
|
||||
new GeneratorNameDeterminationContext() {
|
||||
@Override
|
||||
public Class<?> getIdType() {
|
||||
return buildingContext
|
||||
.getBootstrapContext()
|
||||
.getReflectionManager()
|
||||
.toClass( idXProperty.getType() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGeneratedValueGeneratorName() {
|
||||
return generatedValueAnn.generator();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
log.debugf( "Building implicit generic IdentifierGeneratorDefinition (%s) : %s", name, strategyName );
|
||||
return new IdentifierGeneratorDefinition(
|
||||
return IdentifierGeneratorDefinition.createImplicit(
|
||||
name,
|
||||
strategyName,
|
||||
Collections.singletonMap( IdentifierGenerator.GENERATOR_NAME, name )
|
||||
buildingContext
|
||||
.getBootstrapContext()
|
||||
.getReflectionManager()
|
||||
.toClass( idXProperty.getType() ),
|
||||
generatedValue.generator(),
|
||||
buildingContext.getBuildingOptions().getIdGenerationTypeInterpreter(),
|
||||
interpretGenerationType( generatedValue )
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.hibernate.annotations.OptimisticLock;
|
|||
import org.hibernate.annotations.ValueGenerationType;
|
||||
import org.hibernate.annotations.common.reflection.XClass;
|
||||
import org.hibernate.annotations.common.reflection.XProperty;
|
||||
import org.hibernate.boot.model.relational.ExportableProducer;
|
||||
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||
import org.hibernate.cfg.AccessType;
|
||||
import org.hibernate.cfg.AnnotatedColumns;
|
||||
|
@ -37,6 +38,7 @@ import org.hibernate.mapping.Component;
|
|||
import org.hibernate.mapping.GeneratorCreator;
|
||||
import org.hibernate.mapping.IdentifierGeneratorCreator;
|
||||
import org.hibernate.mapping.KeyValue;
|
||||
import org.hibernate.mapping.MappedSuperclass;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.mapping.RootClass;
|
||||
import org.hibernate.mapping.SimpleValue;
|
||||
|
@ -49,6 +51,7 @@ import org.hibernate.tuple.Generator;
|
|||
import org.hibernate.tuple.AttributeBinder;
|
||||
import org.hibernate.tuple.GeneratorCreationContext;
|
||||
import org.hibernate.tuple.GenerationTiming;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
@ -168,6 +171,38 @@ public class PropertyBinder {
|
|||
this.declaringClassSet = true;
|
||||
}
|
||||
|
||||
private boolean isToOneValue(Value value) {
|
||||
return value instanceof ToOne;
|
||||
}
|
||||
|
||||
public void setProperty(XProperty property) {
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
public void setReturnedClass(XClass returnedClass) {
|
||||
this.returnedClass = returnedClass;
|
||||
}
|
||||
|
||||
public BasicValueBinder getBasicValueBinder() {
|
||||
return basicValueBinder;
|
||||
}
|
||||
|
||||
public Value getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setId(boolean id) {
|
||||
this.isId = id;
|
||||
}
|
||||
|
||||
public boolean isId() {
|
||||
return isId;
|
||||
}
|
||||
|
||||
public void setInheritanceStatePerClass(Map<XClass, InheritanceState> inheritanceStatePerClass) {
|
||||
this.inheritanceStatePerClass = inheritanceStatePerClass;
|
||||
}
|
||||
|
||||
private void validateBind() {
|
||||
if ( property.isAnnotationPresent( Immutable.class ) ) {
|
||||
throw new AnnotationException( "Property '" + qualify( holder.getPath(), name )
|
||||
|
@ -243,7 +278,8 @@ public class PropertyBinder {
|
|||
if ( isId ) {
|
||||
final RootClass rootClass = (RootClass) holder.getPersistentClass();
|
||||
//if an xToMany, it has to be wrapped today.
|
||||
//FIXME this poses a problem as the PK is the class instead of the associated class which is not really compliant with the spec
|
||||
//FIXME this poses a problem as the PK is the class instead of the
|
||||
// associated class which is not really compliant with the spec
|
||||
if ( isXToMany || entityBinder.wrapIdsInEmbeddedComponents() ) {
|
||||
Component identifier = (Component) rootClass.getIdentifier();
|
||||
if (identifier == null) {
|
||||
|
@ -270,7 +306,7 @@ public class PropertyBinder {
|
|||
}
|
||||
else {
|
||||
rootClass.setIdentifierProperty( prop );
|
||||
final org.hibernate.mapping.MappedSuperclass superclass = getMappedSuperclassOrNull(
|
||||
final MappedSuperclass superclass = getMappedSuperclassOrNull(
|
||||
declaringClass,
|
||||
inheritanceStatePerClass,
|
||||
buildingContext
|
||||
|
@ -343,7 +379,7 @@ public class PropertyBinder {
|
|||
}
|
||||
|
||||
private void handleNaturalId(Property prop) {
|
||||
NaturalId naturalId = property.getAnnotation(NaturalId.class);
|
||||
final NaturalId naturalId = property.getAnnotation(NaturalId.class);
|
||||
if ( naturalId != null ) {
|
||||
if ( !entityBinder.isRootEntity() ) {
|
||||
throw new AnnotationException( "Property '" + qualify( holder.getPath(), name )
|
||||
|
@ -415,13 +451,14 @@ 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 <A extends Annotation> GeneratorCreator generatorCreator(XProperty property, A annotation) {
|
||||
public static GeneratorCreator generatorCreator(XProperty property, Annotation annotation) {
|
||||
final Member member = HCANNHelper.getUnderlyingMember( property );
|
||||
final Class<? extends Annotation> annotationType = annotation.annotationType();
|
||||
final ValueGenerationType generatorAnnotation = annotationType.getAnnotation( ValueGenerationType.class );
|
||||
if ( generatorAnnotation == null ) {
|
||||
return null;
|
||||
}
|
||||
checkGeneratorType( generatorAnnotation.generatedBy() );
|
||||
return creationContext -> {
|
||||
final Generator generator =
|
||||
instantiateGenerator(
|
||||
|
@ -438,13 +475,27 @@ public class PropertyBinder {
|
|||
};
|
||||
}
|
||||
|
||||
private static void checkGeneratorType(Class<? extends Generator> generatorClass) {
|
||||
// we don't yet support the additional "fancy" operations of
|
||||
// IdentifierGenerator with regular generators, though this
|
||||
// would be extremely easy to add if anyone asks for it
|
||||
if ( IdentifierGenerator.class.isAssignableFrom( generatorClass ) ) {
|
||||
throw new AnnotationException("Generator class '" + generatorClass.getName()
|
||||
+ "' implements 'IdentifierGenerator' and may not be used with '@ValueGenerationType'");
|
||||
}
|
||||
if ( ExportableProducer.class.isAssignableFrom( generatorClass ) ) {
|
||||
throw new AnnotationException("Generator class '" + generatorClass.getName()
|
||||
+ "' implements 'ExportableProducer' and may not be used with '@ValueGenerationType'");
|
||||
}
|
||||
}
|
||||
|
||||
public static IdentifierGeneratorCreator identifierGeneratorCreator(XProperty idProperty, Annotation annotation) {
|
||||
final Member member = HCANNHelper.getUnderlyingMember( idProperty );
|
||||
final Class<? extends Annotation> annotationType = annotation.annotationType();
|
||||
final IdGeneratorType idGeneratorType = annotationType.getAnnotation( IdGeneratorType.class );
|
||||
assert idGeneratorType != null;
|
||||
return creationContext -> {
|
||||
final IdentifierGenerator generator =
|
||||
final InMemoryGenerator generator =
|
||||
instantiateGenerator(
|
||||
annotation,
|
||||
member,
|
||||
|
@ -505,11 +556,11 @@ public class PropertyBinder {
|
|||
}
|
||||
}
|
||||
|
||||
private void checkVersionGenerationAlways(XProperty property, Generator generator) {
|
||||
private static void checkVersionGenerationAlways(XProperty property, Generator generator) {
|
||||
if ( property.isAnnotationPresent(Version.class) ) {
|
||||
final GenerationTiming timing = generator.getGenerationTiming();
|
||||
if ( !timing.isAlways() ) {
|
||||
throw new AnnotationException("Property '" + qualify( holder.getPath(), name )
|
||||
throw new AnnotationException("Property '" + property.getName()
|
||||
+ "' is annotated '@Version' but has a value generator with timing " + timing.name()
|
||||
+ " (the value generation timing must be ALWAYS)"
|
||||
);
|
||||
|
@ -517,35 +568,4 @@ public class PropertyBinder {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean isToOneValue(Value value) {
|
||||
return value instanceof ToOne;
|
||||
}
|
||||
|
||||
public void setProperty(XProperty property) {
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
public void setReturnedClass(XClass returnedClass) {
|
||||
this.returnedClass = returnedClass;
|
||||
}
|
||||
|
||||
public BasicValueBinder getBasicValueBinder() {
|
||||
return basicValueBinder;
|
||||
}
|
||||
|
||||
public Value getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setId(boolean id) {
|
||||
this.isId = id;
|
||||
}
|
||||
|
||||
public boolean isId() {
|
||||
return isId;
|
||||
}
|
||||
|
||||
public void setInheritanceStatePerClass(Map<XClass, InheritanceState> inheritanceStatePerClass) {
|
||||
this.inheritanceStatePerClass = inheritanceStatePerClass;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -368,7 +368,7 @@ public class PersistentIdentifierBag<E> extends AbstractPersistentCollection<E>
|
|||
final Integer loc = i++;
|
||||
if ( !identifiers.containsKey( loc ) ) {
|
||||
//TODO: native ids
|
||||
final Object id = persister.getIdentifierGenerator().generate( getSession(), entry );
|
||||
final Object id = persister.getGenerator().generate( getSession(), entry, null );
|
||||
identifiers.put( loc, id );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ import org.hibernate.boot.model.relational.QualifiedNameParser;
|
|||
import org.hibernate.boot.model.relational.QualifiedTableName;
|
||||
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.id.OptimizableGenerator;
|
||||
import org.hibernate.id.PostInsertIdentifierGenerator;
|
||||
import org.hibernate.id.enhanced.Optimizer;
|
||||
|
@ -42,6 +41,7 @@ import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
|||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.entity.SingleTableEntityPersister;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
@ -253,8 +253,7 @@ public class TemporaryTable implements Exportable, Contributable {
|
|||
final PersistentClass entityBinding = runtimeModelCreationContext.getBootModel()
|
||||
.getEntityBinding( entityDescriptor.getEntityName() );
|
||||
|
||||
final IdentifierGenerator identifierGenerator = entityDescriptor.getEntityPersister()
|
||||
.getIdentifierGenerator();
|
||||
final InMemoryGenerator identifierGenerator = entityDescriptor.getEntityPersister().getGenerator();
|
||||
final boolean identityColumn = identifierGenerator instanceof PostInsertIdentifierGenerator;
|
||||
final boolean hasOptimizer;
|
||||
if ( identityColumn ) {
|
||||
|
|
|
@ -46,6 +46,7 @@ import org.hibernate.query.spi.QueryEngine;
|
|||
import org.hibernate.relational.SchemaManager;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
@ -183,6 +184,11 @@ public class SessionFactoryDelegatingImpl implements SessionFactoryImplementor,
|
|||
return delegate.getIdentifierGenerator( rootEntityName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public InMemoryGenerator getGenerator(String rootEntityName) {
|
||||
return delegate.getGenerator( rootEntityName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getProperties() {
|
||||
return delegate.getProperties();
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.hibernate.query.sqm.spi.SqmCreationContext;
|
|||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
|
@ -120,9 +121,16 @@ public interface SessionFactoryImplementor
|
|||
|
||||
/**
|
||||
* Get the identifier generator for the hierarchy
|
||||
*
|
||||
* @deprecated use {@link #getGenerator(String)}
|
||||
*/
|
||||
@Deprecated(since = "6.2")
|
||||
IdentifierGenerator getIdentifierGenerator(String rootEntityName);
|
||||
|
||||
/**
|
||||
* Get the identifier generator for the hierarchy
|
||||
*/
|
||||
InMemoryGenerator getGenerator(String rootEntityName);
|
||||
|
||||
EntityNotFoundDelegate getEntityNotFoundDelegate();
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ public abstract class AbstractSaveEventListener<C>
|
|||
processIfSelfDirtinessTracker( entity, SelfDirtinessTracker::$$_hibernate_clearDirtyAttributes );
|
||||
|
||||
EntityPersister persister = source.getEntityPersister( entityName, entity );
|
||||
Object generatedId = persister.getIdentifierGenerator().generate( source, entity );
|
||||
Object generatedId = persister.getGenerator().generate( source, entity, null );
|
||||
if ( generatedId == null ) {
|
||||
throw new IdentifierGenerationException( "null id generated for: " + entity.getClass() );
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ public abstract class AbstractSaveEventListener<C>
|
|||
LOG.debugf(
|
||||
"Generated identifier: %s, using strategy: %s",
|
||||
persister.getIdentifierType().toLoggableString( generatedId, source.getFactory() ),
|
||||
persister.getIdentifierGenerator().getClass().getName()
|
||||
persister.getGenerator().getClass().getName()
|
||||
);
|
||||
}
|
||||
return performSave( entity, generatedId, persister, false, context, source, true );
|
||||
|
|
|
@ -122,7 +122,7 @@ public class DefaultPersistEventListener
|
|||
// NOTE: entityEntry must be null to get here, so we cannot use any of its values
|
||||
final EntityPersister persister = source.getFactory().getMappingMetamodel()
|
||||
.getEntityDescriptor( entityName );
|
||||
if ( persister.getIdentifierGenerator() instanceof ForeignGenerator ) {
|
||||
if ( persister.getGenerator() instanceof ForeignGenerator ) {
|
||||
if ( LOG.isDebugEnabled() && persister.getIdentifier( entity, source ) != null ) {
|
||||
LOG.debug( "Resetting entity id attribute to null for foreign generator" );
|
||||
}
|
||||
|
|
|
@ -22,18 +22,31 @@ import org.hibernate.type.Type;
|
|||
import static org.hibernate.tuple.GenerationTiming.INSERT;
|
||||
|
||||
/**
|
||||
* The general contract between a class that generates unique
|
||||
* identifiers and the {@link org.hibernate.Session}. It is not
|
||||
* intended that this interface ever be exposed to the application.
|
||||
* It <em>is</em> intended that users implement this interface to
|
||||
* provide custom identifier generation strategies.
|
||||
* A classic extension point from the very earliest days of Hibernate,
|
||||
* this interface is now no longer the only way to generate identifiers.
|
||||
* Any {@link InMemoryGenerator} may now be used.
|
||||
* <p>
|
||||
* Implementors should provide a public default constructor.
|
||||
* This interface extends {@code InMemoryGenerator} with some additional
|
||||
* machinery for {@linkplain #configure configuration}, and for caching
|
||||
* {@link #initialize(SqlStringGenerationContext) generated SQL}.
|
||||
* <p>
|
||||
* Implementations that accept configuration parameters should also
|
||||
* implement {@link Configurable}.
|
||||
* Any identifier generator, including a generator which directly implements
|
||||
* {@code InMemoryGenerator}, may also implement {@link ExportableProducer}.
|
||||
* For the sake of convenience, {@code PersistentIdentifierGenerator} extends
|
||||
* {@code ExportableProducer}, in case the implementation needs to export
|
||||
* objects to the database as part of the process of schema export.
|
||||
* <p>
|
||||
* Implementors <em>must</em> be thread-safe
|
||||
* The {@link #configure(Type, Properties, ServiceRegistry)} method accepts
|
||||
* a properties object containing named values. These include:
|
||||
* <ul>
|
||||
* <li>several "standard" parameters with keys defined as static members of
|
||||
* this interface: {@value #ENTITY_NAME}, {@value #JPA_ENTITY_NAME},
|
||||
* {@value #GENERATOR_NAME}, {@value #CONTRIBUTOR_NAME}, along with
|
||||
* <li>additional parameters supplied by Hibernate to its built-in generators,
|
||||
* depending on the generator class, and, possibly,
|
||||
* <li>{@linkplain org.hibernate.annotations.Parameter parameters} specified
|
||||
* using {@link org.hibernate.annotations.GenericGenerator#parameters()}.
|
||||
* </ul>
|
||||
*
|
||||
* @author Gavin King
|
||||
*
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* 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.id.factory.internal;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||
import org.hibernate.engine.config.spi.StandardConverters;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.id.OptimizableGenerator;
|
||||
import org.hibernate.id.PersistentIdentifierGenerator;
|
||||
import org.hibernate.id.enhanced.LegacyNamingStrategy;
|
||||
import org.hibernate.id.enhanced.SingleNamingStrategy;
|
||||
import org.hibernate.id.factory.IdentifierGeneratorFactory;
|
||||
import org.hibernate.mapping.Column;
|
||||
import org.hibernate.mapping.RootClass;
|
||||
import org.hibernate.mapping.SimpleValue;
|
||||
import org.hibernate.mapping.Table;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
public class IdentifierGeneratorUtil {
|
||||
|
||||
public static IdentifierGenerator createLegacyIdentifierGenerator(
|
||||
SimpleValue simpleValue,
|
||||
IdentifierGeneratorFactory identifierGeneratorFactory,
|
||||
Dialect dialect,
|
||||
String defaultCatalog,
|
||||
String defaultSchema,
|
||||
RootClass rootClass) {
|
||||
final Properties params = new Properties();
|
||||
|
||||
// This is for backwards compatibility only;
|
||||
// when this method is called by Hibernate ORM, defaultSchema and defaultCatalog are always
|
||||
// null, and defaults are handled later.
|
||||
if ( defaultSchema != null ) {
|
||||
params.setProperty( PersistentIdentifierGenerator.SCHEMA, defaultSchema);
|
||||
}
|
||||
|
||||
if ( defaultCatalog != null ) {
|
||||
params.setProperty( PersistentIdentifierGenerator.CATALOG, defaultCatalog);
|
||||
}
|
||||
|
||||
// default initial value and allocation size per-JPA defaults
|
||||
params.setProperty( OptimizableGenerator.INITIAL_PARAM, String.valueOf( OptimizableGenerator.DEFAULT_INITIAL_VALUE ) );
|
||||
final ConfigurationService cs = simpleValue.getMetadata().getMetadataBuildingOptions().getServiceRegistry()
|
||||
.getService( ConfigurationService.class );
|
||||
|
||||
final String idNamingStrategy = cs.getSetting(
|
||||
AvailableSettings.ID_DB_STRUCTURE_NAMING_STRATEGY,
|
||||
StandardConverters.STRING,
|
||||
null
|
||||
);
|
||||
|
||||
if ( LegacyNamingStrategy.STRATEGY_NAME.equals( idNamingStrategy )
|
||||
|| LegacyNamingStrategy.class.getName().equals( idNamingStrategy )
|
||||
|| SingleNamingStrategy.STRATEGY_NAME.equals( idNamingStrategy )
|
||||
|| SingleNamingStrategy.class.getName().equals( idNamingStrategy ) ) {
|
||||
params.setProperty( OptimizableGenerator.INCREMENT_PARAM, "1" );
|
||||
}
|
||||
else {
|
||||
params.setProperty(
|
||||
OptimizableGenerator.INCREMENT_PARAM,
|
||||
String.valueOf( OptimizableGenerator.DEFAULT_INCREMENT_SIZE )
|
||||
);
|
||||
}
|
||||
//init the table here instead of earlier, so that we can get a quoted table name
|
||||
//TODO: would it be better to simply pass the qualified table name, instead of
|
||||
// splitting it up into schema/catalog/table names
|
||||
final String tableName = simpleValue.getTable().getQuotedName(dialect);
|
||||
params.setProperty( PersistentIdentifierGenerator.TABLE, tableName );
|
||||
|
||||
//pass the column name (a generated id almost always has a single column)
|
||||
final String columnName = ( (Column) simpleValue.getSelectables().get(0) ).getQuotedName(dialect);
|
||||
params.setProperty( PersistentIdentifierGenerator.PK, columnName );
|
||||
|
||||
//pass the entity-name, if not a collection-id
|
||||
if ( rootClass != null ) {
|
||||
params.setProperty( IdentifierGenerator.ENTITY_NAME, rootClass.getEntityName() );
|
||||
params.setProperty( IdentifierGenerator.JPA_ENTITY_NAME, rootClass.getJpaEntityName() );
|
||||
// The table name is not really a good default for subselect entities, so use the JPA entity name which is short
|
||||
if ( simpleValue.getTable().isSubselect() ) {
|
||||
params.setProperty( OptimizableGenerator.IMPLICIT_NAME_BASE, rootClass.getJpaEntityName() );
|
||||
}
|
||||
else {
|
||||
params.setProperty( OptimizableGenerator.IMPLICIT_NAME_BASE, simpleValue.getTable().getName() );
|
||||
}
|
||||
|
||||
final StringBuilder tables = new StringBuilder();
|
||||
for ( Table table : rootClass.getIdentityTables() ) {
|
||||
tables.append( table.getQuotedName(dialect) );
|
||||
if ( tables.length()>0 ) {
|
||||
tables.append( ", " );
|
||||
}
|
||||
}
|
||||
params.setProperty( PersistentIdentifierGenerator.TABLES, tables.toString() );
|
||||
}
|
||||
else {
|
||||
params.setProperty( PersistentIdentifierGenerator.TABLES, tableName );
|
||||
params.setProperty( OptimizableGenerator.IMPLICIT_NAME_BASE, tableName );
|
||||
}
|
||||
|
||||
if ( simpleValue.getIdentifierGeneratorParameters() != null ) {
|
||||
params.putAll( simpleValue.getIdentifierGeneratorParameters() );
|
||||
}
|
||||
|
||||
// TODO : we should pass along all settings once "config lifecycle" is hashed out...
|
||||
|
||||
params.put(
|
||||
IdentifierGenerator.CONTRIBUTOR_NAME,
|
||||
simpleValue.getBuildingContext().getCurrentContributorName()
|
||||
);
|
||||
|
||||
if ( cs.getSettings().get( AvailableSettings.PREFERRED_POOLED_OPTIMIZER ) != null ) {
|
||||
params.put(
|
||||
AvailableSettings.PREFERRED_POOLED_OPTIMIZER,
|
||||
cs.getSettings().get( AvailableSettings.PREFERRED_POOLED_OPTIMIZER )
|
||||
);
|
||||
}
|
||||
|
||||
return identifierGeneratorFactory.createIdentifierGenerator(
|
||||
simpleValue.getIdentifierGeneratorStrategy(),
|
||||
simpleValue.getType(),
|
||||
params
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -52,7 +52,7 @@ import org.hibernate.type.descriptor.java.JavaType;
|
|||
import static org.hibernate.id.factory.IdGenFactoryLogging.ID_GEN_FAC_LOGGER;
|
||||
|
||||
/**
|
||||
* Basic {@code templated} support for {@link org.hibernate.id.factory.IdentifierGeneratorFactory} implementations.
|
||||
* Basic implementation of {@link org.hibernate.id.factory.IdentifierGeneratorFactory}.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
|
|
|
@ -124,6 +124,7 @@ import org.hibernate.service.spi.SessionFactoryServiceRegistryFactory;
|
|||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
import org.hibernate.tool.schema.spi.DelayedDropAction;
|
||||
import org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
@ -183,7 +184,7 @@ public class SessionFactoryImpl implements SessionFactoryImplementor {
|
|||
private volatile DelayedDropAction delayedDropAction;
|
||||
|
||||
// todo : move to MetamodelImpl
|
||||
private final transient Map<String,IdentifierGenerator> identifierGenerators;
|
||||
private final transient Map<String, InMemoryGenerator> identifierGenerators;
|
||||
private final transient Map<String, FilterDefinition> filters;
|
||||
private final transient Map<String, FetchProfile> fetchProfiles;
|
||||
|
||||
|
@ -293,12 +294,14 @@ public class SessionFactoryImpl implements SessionFactoryImplementor {
|
|||
//Generators:
|
||||
this.identifierGenerators = new HashMap<>();
|
||||
bootMetamodel.getEntityBindings().stream().filter( model -> !model.isInherited() ).forEach( model -> {
|
||||
final IdentifierGenerator generator = model.getIdentifier().createIdentifierGenerator(
|
||||
final InMemoryGenerator generator = model.getIdentifier().createGenerator(
|
||||
bootstrapContext.getIdentifierGeneratorFactory(),
|
||||
jdbcServices.getJdbcEnvironment().getDialect(),
|
||||
(RootClass) model
|
||||
);
|
||||
generator.initialize( sqlStringGenerationContext );
|
||||
if ( generator instanceof IdentifierGenerator ) {
|
||||
( (IdentifierGenerator) generator ).initialize( sqlStringGenerationContext );
|
||||
}
|
||||
identifierGenerators.put( model.getEntityName(), generator );
|
||||
} );
|
||||
bootMetamodel.validate();
|
||||
|
@ -985,8 +988,14 @@ public class SessionFactoryImpl implements SessionFactoryImplementor {
|
|||
return unmodifiableSet( fetchProfiles.keySet() );
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public IdentifierGenerator getIdentifierGenerator(String rootEntityName) {
|
||||
return identifierGenerators.get(rootEntityName);
|
||||
return (IdentifierGenerator) getGenerator( rootEntityName );
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public InMemoryGenerator getGenerator(String rootEntityName) {
|
||||
return identifierGenerators.get( rootEntityName );
|
||||
}
|
||||
|
||||
private boolean canAccessTransactionManager() {
|
||||
|
|
|
@ -93,7 +93,7 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
|
|||
public Object insert(String entityName, Object entity) {
|
||||
checkOpen();
|
||||
EntityPersister persister = getEntityPersister( entityName, entity );
|
||||
Object id = persister.getIdentifierGenerator().generate( this, entity );
|
||||
Object id = persister.getGenerator().generate( this, entity, null );
|
||||
Object[] state = persister.getValues( entity );
|
||||
if ( persister.isVersioned() ) {
|
||||
boolean substitute = Versioning.seedVersion(
|
||||
|
|
|
@ -18,6 +18,7 @@ import java.util.stream.Collectors;
|
|||
import org.hibernate.MappingException;
|
||||
import org.hibernate.Remove;
|
||||
import org.hibernate.boot.model.relational.Database;
|
||||
import org.hibernate.boot.model.relational.ExportableProducer;
|
||||
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
|
||||
import org.hibernate.boot.model.source.internal.hbm.MappingDocument;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
|
@ -33,6 +34,7 @@ import org.hibernate.internal.util.collections.ArrayHelper;
|
|||
import org.hibernate.internal.util.collections.JoinedIterator;
|
||||
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
|
||||
import org.hibernate.property.access.spi.Setter;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
import org.hibernate.type.ComponentType;
|
||||
import org.hibernate.type.EmbeddedComponentType;
|
||||
import org.hibernate.type.Type;
|
||||
|
@ -70,7 +72,7 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
|
|||
// lazily computed based on 'properties' field: invalidate by setting to null when properties are modified
|
||||
private transient List<Column> cachedColumns;
|
||||
|
||||
private transient IdentifierGenerator builtIdentifierGenerator;
|
||||
private transient InMemoryGenerator builtIdentifierGenerator;
|
||||
|
||||
public Component(MetadataBuildingContext metadata, PersistentClass owner) throws MappingException {
|
||||
this( metadata, owner.getTable(), owner );
|
||||
|
@ -412,34 +414,30 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
|
|||
}
|
||||
|
||||
@Override
|
||||
public IdentifierGenerator createIdentifierGenerator(
|
||||
public InMemoryGenerator createGenerator(
|
||||
IdentifierGeneratorFactory identifierGeneratorFactory,
|
||||
Dialect dialect,
|
||||
String defaultCatalog,
|
||||
String defaultSchema,
|
||||
RootClass rootClass) throws MappingException {
|
||||
if ( builtIdentifierGenerator == null ) {
|
||||
builtIdentifierGenerator = buildIdentifierGenerator(
|
||||
identifierGeneratorFactory,
|
||||
dialect,
|
||||
defaultCatalog,
|
||||
defaultSchema,
|
||||
rootClass
|
||||
);
|
||||
}
|
||||
return builtIdentifierGenerator;
|
||||
}
|
||||
|
||||
private IdentifierGenerator buildIdentifierGenerator(
|
||||
private InMemoryGenerator buildIdentifierGenerator(
|
||||
IdentifierGeneratorFactory identifierGeneratorFactory,
|
||||
Dialect dialect,
|
||||
String defaultCatalog,
|
||||
String defaultSchema,
|
||||
RootClass rootClass) throws MappingException {
|
||||
final boolean hasCustomGenerator = ! DEFAULT_ID_GEN_STRATEGY.equals( getIdentifierGeneratorStrategy() );
|
||||
if ( hasCustomGenerator ) {
|
||||
return super.createIdentifierGenerator(
|
||||
identifierGeneratorFactory, dialect, defaultCatalog, defaultSchema, rootClass
|
||||
return super.createGenerator(
|
||||
identifierGeneratorFactory,
|
||||
dialect,
|
||||
rootClass
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -469,25 +467,16 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
|
|||
if ( property.getValue().isSimpleValue() ) {
|
||||
final SimpleValue value = (SimpleValue) property.getValue();
|
||||
|
||||
if ( DEFAULT_ID_GEN_STRATEGY.equals( value.getIdentifierGeneratorStrategy() ) ) {
|
||||
if ( !DEFAULT_ID_GEN_STRATEGY.equals( value.getIdentifierGeneratorStrategy() ) ) {
|
||||
// skip any 'assigned' generators, they would have been handled by
|
||||
// the StandardGenerationContextLocator
|
||||
continue;
|
||||
generator.addGeneratedValuePlan(
|
||||
new ValueGenerationPlan(
|
||||
value.createGenerator( identifierGeneratorFactory, dialect, rootClass ),
|
||||
injector( property, attributeDeclarer )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
final IdentifierGenerator valueGenerator = value.createIdentifierGenerator(
|
||||
identifierGeneratorFactory,
|
||||
dialect,
|
||||
defaultCatalog,
|
||||
defaultSchema,
|
||||
rootClass
|
||||
);
|
||||
generator.addGeneratedValuePlan(
|
||||
new ValueGenerationPlan(
|
||||
valueGenerator,
|
||||
injector( property, attributeDeclarer )
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
return generator;
|
||||
|
@ -523,11 +512,11 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
|
|||
}
|
||||
|
||||
public static class ValueGenerationPlan implements CompositeNestedGeneratedValueGenerator.GenerationPlan {
|
||||
private final IdentifierGenerator subGenerator;
|
||||
private final InMemoryGenerator subGenerator;
|
||||
private final Setter injector;
|
||||
|
||||
public ValueGenerationPlan(
|
||||
IdentifierGenerator subGenerator,
|
||||
InMemoryGenerator subGenerator,
|
||||
Setter injector) {
|
||||
this.subGenerator = subGenerator;
|
||||
this.injector = injector;
|
||||
|
@ -535,18 +524,21 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
|
|||
|
||||
@Override
|
||||
public void execute(SharedSessionContractImplementor session, Object incomingObject, Object injectionContext) {
|
||||
final Object generatedValue = subGenerator.generate( session, incomingObject );
|
||||
injector.set( injectionContext, generatedValue );
|
||||
injector.set( injectionContext, subGenerator.generate( session, incomingObject, null ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerExportables(Database database) {
|
||||
subGenerator.registerExportables( database );
|
||||
if ( subGenerator instanceof ExportableProducer ) {
|
||||
( (ExportableProducer) subGenerator ).registerExportables( database );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(SqlStringGenerationContext context) {
|
||||
subGenerator.initialize( context );
|
||||
if ( subGenerator instanceof IdentifierGenerator ) {
|
||||
( (IdentifierGenerator) subGenerator ).initialize( context );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
*/
|
||||
package org.hibernate.mapping;
|
||||
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.id.factory.spi.CustomIdGeneratorCreationContext;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface IdentifierGeneratorCreator {
|
||||
IdentifierGenerator createGenerator(CustomIdGeneratorCreationContext context);
|
||||
InMemoryGenerator createGenerator(CustomIdGeneratorCreationContext context);
|
||||
}
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
*/
|
||||
package org.hibernate.mapping;
|
||||
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.id.factory.IdentifierGeneratorFactory;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
|
||||
/**
|
||||
* A mapping model {@link Value} which may be treated as an identifying key of a
|
||||
|
@ -21,23 +21,6 @@ import org.hibernate.id.factory.IdentifierGeneratorFactory;
|
|||
*/
|
||||
public interface KeyValue extends Value {
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #createIdentifierGenerator(IdentifierGeneratorFactory, Dialect, RootClass)}
|
||||
* instead.
|
||||
*/
|
||||
@Deprecated
|
||||
IdentifierGenerator createIdentifierGenerator(
|
||||
IdentifierGeneratorFactory identifierGeneratorFactory,
|
||||
Dialect dialect,
|
||||
String defaultCatalog,
|
||||
String defaultSchema,
|
||||
RootClass rootClass) throws MappingException;
|
||||
|
||||
IdentifierGenerator createIdentifierGenerator(
|
||||
IdentifierGeneratorFactory identifierGeneratorFactory,
|
||||
Dialect dialect,
|
||||
RootClass rootClass) throws MappingException;
|
||||
|
||||
boolean isIdentityColumn(IdentifierGeneratorFactory identifierGeneratorFactory, Dialect dialect);
|
||||
|
||||
ForeignKey createForeignKeyOfEntity(String entityName);
|
||||
|
@ -47,4 +30,34 @@ public interface KeyValue extends Value {
|
|||
String getNullValue();
|
||||
|
||||
boolean isUpdateable();
|
||||
|
||||
InMemoryGenerator createGenerator(
|
||||
IdentifierGeneratorFactory identifierGeneratorFactory,
|
||||
Dialect dialect,
|
||||
RootClass rootClass);
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #createGenerator(IdentifierGeneratorFactory, Dialect, RootClass)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default IdentifierGenerator createIdentifierGenerator(
|
||||
IdentifierGeneratorFactory identifierGeneratorFactory,
|
||||
Dialect dialect,
|
||||
String defaultCatalog,
|
||||
String defaultSchema,
|
||||
RootClass rootClass) {
|
||||
return (IdentifierGenerator) createGenerator( identifierGeneratorFactory, dialect, rootClass );
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #createGenerator(IdentifierGeneratorFactory, Dialect, RootClass)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default IdentifierGenerator createIdentifierGenerator(
|
||||
IdentifierGeneratorFactory identifierGeneratorFactory,
|
||||
Dialect dialect,
|
||||
RootClass rootClass) {
|
||||
return (IdentifierGenerator) createGenerator( identifierGeneratorFactory, dialect, rootClass );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,17 +34,10 @@ import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
|||
import org.hibernate.boot.spi.InFlightMetadataCollector;
|
||||
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||
import org.hibernate.boot.spi.MetadataImplementor;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||
import org.hibernate.engine.config.spi.StandardConverters;
|
||||
import org.hibernate.engine.spi.Mapping;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.id.IdentityGenerator;
|
||||
import org.hibernate.id.OptimizableGenerator;
|
||||
import org.hibernate.id.PersistentIdentifierGenerator;
|
||||
import org.hibernate.id.enhanced.LegacyNamingStrategy;
|
||||
import org.hibernate.id.enhanced.SingleNamingStrategy;
|
||||
import org.hibernate.id.factory.IdentifierGeneratorFactory;
|
||||
import org.hibernate.id.factory.spi.CustomIdGeneratorCreationContext;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
|
@ -54,6 +47,7 @@ import org.hibernate.internal.util.collections.ArrayHelper;
|
|||
import org.hibernate.metamodel.model.convert.spi.JpaAttributeConverter;
|
||||
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.descriptor.JdbcTypeNameMapper;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
|
@ -67,6 +61,8 @@ import org.hibernate.usertype.DynamicParameterizedType;
|
|||
|
||||
import jakarta.persistence.AttributeConverter;
|
||||
|
||||
import static org.hibernate.id.factory.internal.IdentifierGeneratorUtil.createLegacyIdentifierGenerator;
|
||||
|
||||
/**
|
||||
* A mapping model object that represents any value that maps to columns.
|
||||
*
|
||||
|
@ -104,6 +100,10 @@ public abstract class SimpleValue implements KeyValue {
|
|||
private ConverterDescriptor attributeConverterDescriptor;
|
||||
private Type type;
|
||||
|
||||
private IdentifierGeneratorCreator customIdGeneratorCreator;
|
||||
private GeneratorCreator customGeneratorCreator;
|
||||
private InMemoryGenerator generator;
|
||||
|
||||
public SimpleValue(MetadataBuildingContext buildingContext) {
|
||||
this.buildingContext = buildingContext;
|
||||
this.metadata = buildingContext.getMetadataCollector();
|
||||
|
@ -136,7 +136,7 @@ public abstract class SimpleValue implements KeyValue {
|
|||
this.attributeConverterDescriptor = original.attributeConverterDescriptor;
|
||||
this.type = original.type;
|
||||
this.customIdGeneratorCreator = original.customIdGeneratorCreator;
|
||||
this.identifierGenerator = original.identifierGenerator;
|
||||
this.generator = original.generator;
|
||||
}
|
||||
|
||||
public MetadataBuildingContext getBuildingContext() {
|
||||
|
@ -359,9 +359,6 @@ public abstract class SimpleValue implements KeyValue {
|
|||
getTable().createUniqueKey( getConstraintColumns() );
|
||||
}
|
||||
|
||||
private IdentifierGeneratorCreator customIdGeneratorCreator;
|
||||
private IdentifierGenerator identifierGenerator;
|
||||
|
||||
/**
|
||||
* Returns the cached {@link IdentifierGenerator}, or null if
|
||||
* {@link #createIdentifierGenerator(IdentifierGeneratorFactory, Dialect, String, String, RootClass)}
|
||||
|
@ -371,7 +368,7 @@ public abstract class SimpleValue implements KeyValue {
|
|||
*/
|
||||
@Deprecated(since = "6.0")
|
||||
public IdentifierGenerator getIdentifierGenerator() {
|
||||
return identifierGenerator;
|
||||
return (IdentifierGenerator) generator;
|
||||
}
|
||||
|
||||
public void setCustomIdGeneratorCreator(IdentifierGeneratorCreator customIdGeneratorCreator) {
|
||||
|
@ -382,171 +379,41 @@ public abstract class SimpleValue implements KeyValue {
|
|||
return customIdGeneratorCreator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentifierGenerator createIdentifierGenerator(
|
||||
IdentifierGeneratorFactory identifierGeneratorFactory,
|
||||
Dialect dialect,
|
||||
RootClass rootClass) throws MappingException {
|
||||
return createIdentifierGenerator( identifierGeneratorFactory, dialect, null, null, rootClass );
|
||||
public GeneratorCreator getCustomGeneratorCreator() {
|
||||
return customGeneratorCreator;
|
||||
}
|
||||
|
||||
public void setCustomGeneratorCreator(GeneratorCreator customGeneratorCreator) {
|
||||
this.customGeneratorCreator = customGeneratorCreator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentifierGenerator createIdentifierGenerator(
|
||||
public InMemoryGenerator createGenerator(
|
||||
IdentifierGeneratorFactory identifierGeneratorFactory,
|
||||
Dialect dialect,
|
||||
String defaultCatalog,
|
||||
String defaultSchema,
|
||||
Dialect dialect,
|
||||
RootClass rootClass) throws MappingException {
|
||||
if ( identifierGenerator != null ) {
|
||||
return identifierGenerator;
|
||||
if ( generator != null ) {
|
||||
return generator;
|
||||
}
|
||||
|
||||
if ( customIdGeneratorCreator != null ) {
|
||||
final CustomIdGeneratorCreationContext creationContext = new CustomIdGeneratorCreationContext() {
|
||||
@Override
|
||||
public IdentifierGeneratorFactory getIdentifierGeneratorFactory() {
|
||||
return identifierGeneratorFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Database getDatabase() {
|
||||
return buildingContext.getMetadataCollector().getDatabase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceRegistry getServiceRegistry() {
|
||||
return buildingContext.getBootstrapContext().getServiceRegistry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultCatalog() {
|
||||
return defaultCatalog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultSchema() {
|
||||
return defaultSchema;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RootClass getRootClass() {
|
||||
return rootClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistentClass getPersistentClass() {
|
||||
return rootClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Property getProperty() {
|
||||
return rootClass.getIdentifierProperty();
|
||||
}
|
||||
};
|
||||
|
||||
identifierGenerator = customIdGeneratorCreator.createGenerator( creationContext );
|
||||
return identifierGenerator;
|
||||
}
|
||||
|
||||
final Properties params = new Properties();
|
||||
|
||||
// This is for backwards compatibility only;
|
||||
// when this method is called by Hibernate ORM, defaultSchema and defaultCatalog are always
|
||||
// null, and defaults are handled later.
|
||||
if ( defaultSchema != null ) {
|
||||
params.setProperty( PersistentIdentifierGenerator.SCHEMA, defaultSchema);
|
||||
}
|
||||
|
||||
if ( defaultCatalog != null ) {
|
||||
params.setProperty( PersistentIdentifierGenerator.CATALOG, defaultCatalog );
|
||||
}
|
||||
|
||||
// default initial value and allocation size per-JPA defaults
|
||||
params.setProperty( OptimizableGenerator.INITIAL_PARAM, String.valueOf( OptimizableGenerator.DEFAULT_INITIAL_VALUE ) );
|
||||
final ConfigurationService cs = metadata.getMetadataBuildingOptions().getServiceRegistry()
|
||||
.getService( ConfigurationService.class );
|
||||
|
||||
final String idNamingStrategy = cs.getSetting(
|
||||
AvailableSettings.ID_DB_STRUCTURE_NAMING_STRATEGY,
|
||||
StandardConverters.STRING,
|
||||
null
|
||||
);
|
||||
|
||||
if ( LegacyNamingStrategy.STRATEGY_NAME.equals( idNamingStrategy )
|
||||
|| LegacyNamingStrategy.class.getName().equals( idNamingStrategy )
|
||||
|| SingleNamingStrategy.STRATEGY_NAME.equals( idNamingStrategy )
|
||||
|| SingleNamingStrategy.class.getName().equals( idNamingStrategy ) ) {
|
||||
params.setProperty( OptimizableGenerator.INCREMENT_PARAM, "1" );
|
||||
}
|
||||
else {
|
||||
params.setProperty(
|
||||
OptimizableGenerator.INCREMENT_PARAM,
|
||||
String.valueOf( OptimizableGenerator.DEFAULT_INCREMENT_SIZE )
|
||||
generator = customIdGeneratorCreator.createGenerator(
|
||||
new IdGeneratorCreationContext( identifierGeneratorFactory, null, null, rootClass )
|
||||
);
|
||||
return generator;
|
||||
}
|
||||
//init the table here instead of earlier, so that we can get a quoted table name
|
||||
//TODO: would it be better to simply pass the qualified table name, instead of
|
||||
// splitting it up into schema/catalog/table names
|
||||
final String tableName = getTable().getQuotedName( dialect );
|
||||
params.setProperty( PersistentIdentifierGenerator.TABLE, tableName );
|
||||
|
||||
//pass the column name (a generated id almost always has a single column)
|
||||
final String columnName = ( (Column) getSelectables().get(0) ).getQuotedName( dialect );
|
||||
params.setProperty( PersistentIdentifierGenerator.PK, columnName );
|
||||
|
||||
//pass the entity-name, if not a collection-id
|
||||
if ( rootClass != null ) {
|
||||
params.setProperty( IdentifierGenerator.ENTITY_NAME, rootClass.getEntityName() );
|
||||
params.setProperty( IdentifierGenerator.JPA_ENTITY_NAME, rootClass.getJpaEntityName() );
|
||||
// The table name is not really a good default for subselect entities, so use the JPA entity name which is short
|
||||
if ( getTable().isSubselect() ) {
|
||||
params.setProperty( OptimizableGenerator.IMPLICIT_NAME_BASE, rootClass.getJpaEntityName() );
|
||||
}
|
||||
else {
|
||||
params.setProperty( OptimizableGenerator.IMPLICIT_NAME_BASE, getTable().getName() );
|
||||
}
|
||||
|
||||
final StringBuilder tables = new StringBuilder();
|
||||
final Iterator<Table> itr = rootClass.getIdentityTables().iterator();
|
||||
while ( itr.hasNext() ) {
|
||||
final Table table = itr.next();
|
||||
tables.append( table.getQuotedName( dialect ) );
|
||||
if ( itr.hasNext() ) {
|
||||
tables.append( ", " );
|
||||
}
|
||||
}
|
||||
params.setProperty( PersistentIdentifierGenerator.TABLES, tables.toString() );
|
||||
}
|
||||
else {
|
||||
params.setProperty( PersistentIdentifierGenerator.TABLES, tableName );
|
||||
params.setProperty( OptimizableGenerator.IMPLICIT_NAME_BASE, tableName );
|
||||
}
|
||||
|
||||
if ( identifierGeneratorParameters != null ) {
|
||||
params.putAll(identifierGeneratorParameters);
|
||||
}
|
||||
|
||||
// TODO : we should pass along all settings once "config lifecycle" is hashed out...
|
||||
|
||||
params.put(
|
||||
IdentifierGenerator.CONTRIBUTOR_NAME,
|
||||
buildingContext.getCurrentContributorName()
|
||||
);
|
||||
|
||||
if ( cs.getSettings().get( AvailableSettings.PREFERRED_POOLED_OPTIMIZER ) != null ) {
|
||||
params.put(
|
||||
AvailableSettings.PREFERRED_POOLED_OPTIMIZER,
|
||||
cs.getSettings().get( AvailableSettings.PREFERRED_POOLED_OPTIMIZER )
|
||||
else if ( customGeneratorCreator != null ) {
|
||||
// we may as well allow this, so you don't have to annotate generator
|
||||
// annotations twice, with @IdGeneratorType and @ValueGenerationType
|
||||
//TODO: this typecast is ugly ... throw a better exception at least
|
||||
generator = (InMemoryGenerator) customGeneratorCreator.createGenerator(
|
||||
new IdGeneratorCreationContext( identifierGeneratorFactory, null, null, rootClass )
|
||||
);
|
||||
return generator;
|
||||
}
|
||||
|
||||
identifierGenerator = identifierGeneratorFactory.createIdentifierGenerator(
|
||||
identifierGeneratorStrategy,
|
||||
getType(),
|
||||
params
|
||||
);
|
||||
|
||||
return identifierGenerator;
|
||||
generator = createLegacyIdentifierGenerator(this, identifierGeneratorFactory, dialect, null, null, rootClass );
|
||||
return generator;
|
||||
}
|
||||
|
||||
public boolean isUpdateable() {
|
||||
|
@ -1185,4 +1052,58 @@ public abstract class SimpleValue implements KeyValue {
|
|||
return columnLengths;
|
||||
}
|
||||
}
|
||||
|
||||
private class IdGeneratorCreationContext implements CustomIdGeneratorCreationContext {
|
||||
private final IdentifierGeneratorFactory identifierGeneratorFactory;
|
||||
private final String defaultCatalog;
|
||||
private final String defaultSchema;
|
||||
private final RootClass rootClass;
|
||||
|
||||
public IdGeneratorCreationContext(IdentifierGeneratorFactory identifierGeneratorFactory, String defaultCatalog, String defaultSchema, RootClass rootClass) {
|
||||
this.identifierGeneratorFactory = identifierGeneratorFactory;
|
||||
this.defaultCatalog = defaultCatalog;
|
||||
this.defaultSchema = defaultSchema;
|
||||
this.rootClass = rootClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentifierGeneratorFactory getIdentifierGeneratorFactory() {
|
||||
return identifierGeneratorFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Database getDatabase() {
|
||||
return buildingContext.getMetadataCollector().getDatabase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceRegistry getServiceRegistry() {
|
||||
return buildingContext.getBootstrapContext().getServiceRegistry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultCatalog() {
|
||||
return defaultCatalog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultSchema() {
|
||||
return defaultSchema;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RootClass getRootClass() {
|
||||
return rootClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistentClass getPersistentClass() {
|
||||
return rootClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Property getProperty() {
|
||||
return rootClass.getIdentifierProperty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,6 +128,7 @@ import org.hibernate.sql.model.jdbc.JdbcDeleteMutation;
|
|||
import org.hibernate.sql.model.jdbc.JdbcMutationOperation;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
import org.hibernate.type.CollectionType;
|
||||
import org.hibernate.type.CompositeType;
|
||||
import org.hibernate.type.EntityType;
|
||||
|
@ -225,7 +226,7 @@ public abstract class AbstractCollectionPersister
|
|||
protected final SqlExceptionHelper sqlExceptionHelper;
|
||||
private final SessionFactoryImplementor factory;
|
||||
private final EntityPersister ownerPersister;
|
||||
private final IdentifierGenerator identifierGenerator;
|
||||
private final InMemoryGenerator identifierGenerator;
|
||||
private final PropertyMapping elementPropertyMapping;
|
||||
private final EntityPersister elementPersister;
|
||||
private final CollectionDataAccess cacheAccessStrategy;
|
||||
|
@ -509,12 +510,14 @@ public abstract class AbstractCollectionPersister
|
|||
Column col = idColl.getIdentifier().getColumns().get(0);
|
||||
identifierColumnName = col.getQuotedName( dialect );
|
||||
identifierColumnAlias = col.getAlias( dialect );
|
||||
identifierGenerator = idColl.getIdentifier().createIdentifierGenerator(
|
||||
identifierGenerator = idColl.getIdentifier().createGenerator(
|
||||
creationContext.getBootstrapContext().getIdentifierGeneratorFactory(),
|
||||
factory.getJdbcServices().getDialect(),
|
||||
null
|
||||
);
|
||||
identifierGenerator.initialize( creationContext.getSessionFactory().getSqlStringGenerationContext() );
|
||||
if ( identifierGenerator instanceof IdentifierGenerator ) {
|
||||
( (IdentifierGenerator) identifierGenerator ).initialize( creationContext.getSessionFactory().getSqlStringGenerationContext() );
|
||||
}
|
||||
}
|
||||
else {
|
||||
identifierType = null;
|
||||
|
@ -1139,8 +1142,13 @@ public abstract class AbstractCollectionPersister
|
|||
return ownerPersister;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @Deprecated
|
||||
public IdentifierGenerator getIdentifierGenerator() {
|
||||
return (IdentifierGenerator) identifierGenerator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InMemoryGenerator getGenerator() {
|
||||
return identifierGenerator;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
import org.hibernate.type.CollectionType;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
|
@ -231,9 +232,19 @@ public interface CollectionPersister extends Restrictable {
|
|||
|
||||
/**
|
||||
* Get the surrogate key generation strategy (optional operation)
|
||||
*
|
||||
* @deprecated use {@link #getGenerator()}
|
||||
*/
|
||||
@Deprecated
|
||||
IdentifierGenerator getIdentifierGenerator();
|
||||
|
||||
/**
|
||||
* Get the surrogate key generation strategy (optional operation)
|
||||
*/
|
||||
default InMemoryGenerator getGenerator() {
|
||||
return getIdentifierGenerator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of the surrogate key
|
||||
*/
|
||||
|
|
|
@ -259,6 +259,7 @@ import org.hibernate.stat.spi.StatisticsImplementor;
|
|||
import org.hibernate.tuple.Generator;
|
||||
import org.hibernate.tuple.InDatabaseGenerator;
|
||||
import org.hibernate.tuple.GenerationTiming;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
import org.hibernate.tuple.NonIdentifierAttribute;
|
||||
import org.hibernate.tuple.entity.EntityBasedAssociationAttribute;
|
||||
import org.hibernate.tuple.entity.EntityMetamodel;
|
||||
|
@ -3936,11 +3937,16 @@ public abstract class AbstractEntityPersister
|
|||
return entityMetamodel.isLazy() && !entityMetamodel.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @Deprecated
|
||||
public IdentifierGenerator getIdentifierGenerator() throws HibernateException {
|
||||
return entityMetamodel.getIdentifierProperty().getIdentifierGenerator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InMemoryGenerator getGenerator() {
|
||||
return entityMetamodel.getIdentifierProperty().getGenerator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRootEntityName() {
|
||||
return entityMetamodel.getRootName();
|
||||
|
@ -4821,9 +4827,9 @@ public abstract class AbstractEntityPersister
|
|||
sqmMultiTableMutationStrategy = null;
|
||||
}
|
||||
|
||||
if ( !needsMultiTableInsert && getIdentifierGenerator() instanceof BulkInsertionCapableIdentifierGenerator ) {
|
||||
if ( getIdentifierGenerator() instanceof OptimizableGenerator ) {
|
||||
final Optimizer optimizer = ( (OptimizableGenerator) getIdentifierGenerator() ).getOptimizer();
|
||||
if ( !needsMultiTableInsert && getGenerator() instanceof BulkInsertionCapableIdentifierGenerator ) {
|
||||
if ( getGenerator() instanceof OptimizableGenerator ) {
|
||||
final Optimizer optimizer = ( (OptimizableGenerator) getGenerator() ).getOptimizer();
|
||||
needsMultiTableInsert = optimizer != null && optimizer.getIncrementSize() > 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
|||
import org.hibernate.sql.ast.spi.SqlAliasStemHelper;
|
||||
import org.hibernate.sql.ast.tree.from.RootTableGroupProducer;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
import org.hibernate.tuple.entity.EntityMetamodel;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.Type;
|
||||
|
@ -451,9 +452,16 @@ public interface EntityPersister
|
|||
* Determine which identifier generation strategy is used for this entity.
|
||||
*
|
||||
* @return The identifier generation strategy.
|
||||
*
|
||||
* @deprecated use {@link #getGenerator()}
|
||||
*/
|
||||
@Deprecated
|
||||
IdentifierGenerator getIdentifierGenerator();
|
||||
|
||||
default InMemoryGenerator getGenerator() {
|
||||
return getIdentifierGenerator();
|
||||
}
|
||||
|
||||
@Override
|
||||
default AttributeMapping getAttributeMapping(int position) {
|
||||
return getAttributeMappings().get( position );
|
||||
|
|
|
@ -112,7 +112,7 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
|
|||
|
||||
super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext );
|
||||
|
||||
if ( getIdentifierGenerator() instanceof IdentityGenerator ) {
|
||||
if ( getGenerator() instanceof IdentityGenerator ) {
|
||||
throw new MappingException(
|
||||
"Cannot use identity column key generation with <union-subclass> mapping for: " +
|
||||
getEntityName()
|
||||
|
|
|
@ -44,7 +44,6 @@ import org.hibernate.graph.RootGraph;
|
|||
import org.hibernate.graph.spi.AppliedGraph;
|
||||
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||
import org.hibernate.id.BulkInsertionCapableIdentifierGenerator;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.id.OptimizableGenerator;
|
||||
import org.hibernate.id.enhanced.Optimizer;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
|
@ -108,6 +107,7 @@ import org.hibernate.query.sqm.tree.update.SqmAssignment;
|
|||
import org.hibernate.query.sqm.tree.update.SqmUpdateStatement;
|
||||
import org.hibernate.sql.results.internal.TupleMetadata;
|
||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
|
||||
import static org.hibernate.jpa.HibernateHints.HINT_CACHEABLE;
|
||||
import static org.hibernate.jpa.HibernateHints.HINT_CACHE_MODE;
|
||||
|
@ -838,8 +838,9 @@ public class QuerySqmImpl<R>
|
|||
|
||||
boolean useMultiTableInsert = entityDescriptor.isMultiTable();
|
||||
if ( !useMultiTableInsert && !isSimpleValuesInsert( sqmInsert, entityDescriptor ) ) {
|
||||
final IdentifierGenerator identifierGenerator = entityDescriptor.getIdentifierGenerator();
|
||||
if ( identifierGenerator instanceof BulkInsertionCapableIdentifierGenerator && identifierGenerator instanceof OptimizableGenerator ) {
|
||||
final InMemoryGenerator identifierGenerator = entityDescriptor.getGenerator();
|
||||
if ( identifierGenerator instanceof BulkInsertionCapableIdentifierGenerator
|
||||
&& identifierGenerator instanceof OptimizableGenerator ) {
|
||||
final Optimizer optimizer = ( (OptimizableGenerator) identifierGenerator ).getOptimizer();
|
||||
if ( optimizer != null && optimizer.getIncrementSize() > 1 ) {
|
||||
useMultiTableInsert = !hasIdentifierAssigned( sqmInsert, entityDescriptor );
|
||||
|
|
|
@ -21,7 +21,6 @@ import org.hibernate.dialect.temptable.TemporaryTable;
|
|||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.id.BulkInsertionCapableIdentifierGenerator;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.id.OptimizableGenerator;
|
||||
import org.hibernate.id.PostInsertIdentifierGenerator;
|
||||
import org.hibernate.id.enhanced.Optimizer;
|
||||
|
@ -95,6 +94,7 @@ import org.hibernate.sql.results.graph.DomainResult;
|
|||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
|
@ -273,7 +273,7 @@ public class CteInsertHandler implements InsertHandler {
|
|||
rowNumberColumn
|
||||
);
|
||||
}
|
||||
if ( !assignsId && entityDescriptor.getIdentifierGenerator() instanceof PostInsertIdentifierGenerator ) {
|
||||
if ( !assignsId && entityDescriptor.getGenerator() instanceof PostInsertIdentifierGenerator ) {
|
||||
querySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
|
@ -337,7 +337,7 @@ public class CteInsertHandler implements InsertHandler {
|
|||
processingStateStack.push( oldState );
|
||||
sqmConverter.pruneTableGroupJoins();
|
||||
|
||||
if ( !assignsId && entityDescriptor.getIdentifierGenerator() instanceof PostInsertIdentifierGenerator ) {
|
||||
if ( !assignsId && entityDescriptor.getGenerator() instanceof PostInsertIdentifierGenerator ) {
|
||||
// Add the row number to the assignments
|
||||
final CteColumn rowNumberColumn = cteTable.getCteColumns()
|
||||
.get( cteTable.getCteColumns().size() - 1 );
|
||||
|
@ -389,7 +389,7 @@ public class CteInsertHandler implements InsertHandler {
|
|||
);
|
||||
final CteColumn idColumn = fullEntityCteTable.getCteColumns().get( 0 );
|
||||
final BasicValuedMapping idType = (BasicValuedMapping) idColumn.getJdbcMapping();
|
||||
final Optimizer optimizer = ( (OptimizableGenerator) entityDescriptor.getIdentifierGenerator() ).getOptimizer();
|
||||
final Optimizer optimizer = ( (OptimizableGenerator) entityDescriptor.getGenerator() ).getOptimizer();
|
||||
final BasicValuedMapping integerType = (BasicValuedMapping) rowNumberColumn.getJdbcMapping();
|
||||
final Expression rowNumberMinusOneModuloIncrement = new BinaryArithmeticExpression(
|
||||
new BinaryArithmeticExpression(
|
||||
|
@ -428,7 +428,7 @@ public class CteInsertHandler implements InsertHandler {
|
|||
rowNumberColumnReference
|
||||
)
|
||||
);
|
||||
final String fragment = ( (BulkInsertionCapableIdentifierGenerator) entityDescriptor.getIdentifierGenerator() )
|
||||
final String fragment = ( (BulkInsertionCapableIdentifierGenerator) entityDescriptor.getGenerator() )
|
||||
.determineBulkInsertionIdentifierGenerationSelectFragment(
|
||||
sessionFactory.getSqlStringGenerationContext()
|
||||
);
|
||||
|
@ -581,7 +581,7 @@ public class CteInsertHandler implements InsertHandler {
|
|||
statement.addCteStatement( entityCte );
|
||||
}
|
||||
}
|
||||
else if ( !assignsId && entityDescriptor.getIdentifierGenerator() instanceof PostInsertIdentifierGenerator ) {
|
||||
else if ( !assignsId && entityDescriptor.getGenerator() instanceof PostInsertIdentifierGenerator ) {
|
||||
final String baseTableName = "base_" + entityCteTable.getTableExpression();
|
||||
final CteStatement baseEntityCte = new CteStatement(
|
||||
entityCteTable.withName( baseTableName ),
|
||||
|
@ -775,7 +775,7 @@ public class CteInsertHandler implements InsertHandler {
|
|||
true
|
||||
);
|
||||
|
||||
final IdentifierGenerator identifierGenerator = entityDescriptor.getEntityPersister().getIdentifierGenerator();
|
||||
final InMemoryGenerator identifierGenerator = entityDescriptor.getEntityPersister().getGenerator();
|
||||
final List<Map.Entry<List<CteColumn>, Assignment>> tableAssignments = assignmentsByTable.get( rootTableReference );
|
||||
if ( ( tableAssignments == null || tableAssignments.isEmpty() ) && !( identifierGenerator instanceof PostInsertIdentifierGenerator ) ) {
|
||||
throw new IllegalStateException( "There must be at least a single root table assignment" );
|
||||
|
|
|
@ -23,7 +23,6 @@ import org.hibernate.engine.jdbc.spi.JdbcServices;
|
|||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.id.BulkInsertionCapableIdentifierGenerator;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.id.OptimizableGenerator;
|
||||
import org.hibernate.id.PostInsertIdentifierGenerator;
|
||||
import org.hibernate.id.PostInsertIdentityPersister;
|
||||
|
@ -74,6 +73,7 @@ import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
|||
import org.hibernate.sql.results.graph.basic.BasicFetch;
|
||||
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
import org.hibernate.type.descriptor.ValueBinder;
|
||||
|
||||
/**
|
||||
|
@ -301,7 +301,7 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio
|
|||
true
|
||||
);
|
||||
|
||||
final IdentifierGenerator identifierGenerator = entityDescriptor.getEntityPersister().getIdentifierGenerator();
|
||||
final InMemoryGenerator identifierGenerator = entityDescriptor.getEntityPersister().getGenerator();
|
||||
final List<Assignment> assignments = assignmentsByTable.get( updatingTableReference );
|
||||
if ( ( assignments == null || assignments.isEmpty() )
|
||||
&& !( identifierGenerator instanceof PostInsertIdentifierGenerator )
|
||||
|
@ -507,10 +507,7 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio
|
|||
rootIdentity,
|
||||
new JdbcParameterBindingImpl(
|
||||
identifierMapping.getJdbcMapping(),
|
||||
identifierGenerator.generate(
|
||||
executionContext.getSession(),
|
||||
null
|
||||
)
|
||||
identifierGenerator.generate( executionContext.getSession(), null, null )
|
||||
)
|
||||
);
|
||||
jdbcServices.getJdbcMutationExecutor().execute(
|
||||
|
@ -654,7 +651,7 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio
|
|||
}
|
||||
}
|
||||
|
||||
private boolean needsIdentifierGeneration(IdentifierGenerator identifierGenerator) {
|
||||
private boolean needsIdentifierGeneration(InMemoryGenerator identifierGenerator) {
|
||||
if ( !( identifierGenerator instanceof OptimizableGenerator ) ) {
|
||||
return false;
|
||||
}
|
||||
|
@ -721,7 +718,7 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio
|
|||
}
|
||||
final String targetKeyColumnName = keyColumns[0];
|
||||
final AbstractEntityPersister entityPersister = (AbstractEntityPersister) entityDescriptor.getEntityPersister();
|
||||
final IdentifierGenerator identifierGenerator = entityPersister.getIdentifierGenerator();
|
||||
final InMemoryGenerator identifierGenerator = entityPersister.getGenerator();
|
||||
final boolean needsKeyInsert;
|
||||
if ( identifierGenerator instanceof PostInsertIdentifierGenerator ) {
|
||||
needsKeyInsert = true;
|
||||
|
|
|
@ -20,7 +20,6 @@ import org.hibernate.dialect.temptable.TemporaryTableColumn;
|
|||
import org.hibernate.dialect.temptable.TemporaryTableSessionUidColumn;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.id.OptimizableGenerator;
|
||||
import org.hibernate.id.enhanced.Optimizer;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
|
@ -53,6 +52,7 @@ import org.hibernate.sql.ast.tree.update.Assignment;
|
|||
import org.hibernate.sql.exec.internal.JdbcParameterImpl;
|
||||
import org.hibernate.sql.exec.spi.ExecutionContext;
|
||||
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
import org.hibernate.type.BasicType;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
@ -201,8 +201,8 @@ public class TableBasedInsertHandler implements InsertHandler {
|
|||
new Assignment( columnReference, columnReference )
|
||||
);
|
||||
}
|
||||
else if ( entityDescriptor.getIdentifierGenerator() instanceof OptimizableGenerator ) {
|
||||
final Optimizer optimizer = ( (OptimizableGenerator) entityDescriptor.getIdentifierGenerator() ).getOptimizer();
|
||||
else if ( entityDescriptor.getGenerator() instanceof OptimizableGenerator ) {
|
||||
final Optimizer optimizer = ( (OptimizableGenerator) entityDescriptor.getGenerator() ).getOptimizer();
|
||||
if ( optimizer != null && optimizer.getIncrementSize() > 1 ) {
|
||||
if ( !sessionFactory.getJdbcServices().getDialect().supportsWindowFunctions() ) {
|
||||
return;
|
||||
|
@ -254,7 +254,7 @@ public class TableBasedInsertHandler implements InsertHandler {
|
|||
}
|
||||
else {
|
||||
// Add the row number column if there is one
|
||||
final IdentifierGenerator generator = entityDescriptor.getIdentifierGenerator();
|
||||
final InMemoryGenerator generator = entityDescriptor.getGenerator();
|
||||
final BasicType<?> rowNumberType;
|
||||
if ( generator instanceof OptimizableGenerator ) {
|
||||
final Optimizer optimizer = ( (OptimizableGenerator) generator ).getOptimizer();
|
||||
|
|
|
@ -44,7 +44,6 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|||
import org.hibernate.graph.spi.AppliedGraph;
|
||||
import org.hibernate.id.BulkInsertionCapableIdentifierGenerator;
|
||||
import org.hibernate.id.CompositeNestedGeneratedValueGenerator;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.id.OptimizableGenerator;
|
||||
import org.hibernate.id.PostInsertIdentifierGenerator;
|
||||
import org.hibernate.id.enhanced.Optimizer;
|
||||
|
@ -384,6 +383,7 @@ import org.hibernate.sql.results.graph.FetchableContainer;
|
|||
import org.hibernate.sql.results.graph.instantiation.internal.DynamicInstantiation;
|
||||
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||
import org.hibernate.sql.results.internal.StandardEntityGraphTraversalStateImpl;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.CustomType;
|
||||
import org.hibernate.type.EnumType;
|
||||
|
@ -1225,18 +1225,13 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
EntityPersister entityDescriptor, TableGroup rootTableGroup) {
|
||||
final List<SqmPath<?>> targetPaths = sqmStatement.getInsertionTargetPaths();
|
||||
final EntityDiscriminatorMapping discriminatorMapping = entityDescriptor.getDiscriminatorMapping();
|
||||
IdentifierGenerator identifierGenerator = entityDescriptor.getIdentifierGenerator();
|
||||
Expression versionExpression = null;
|
||||
Expression discriminatorExpression = null;
|
||||
BasicEntityIdentifierMapping identifierMapping = null;
|
||||
// We use the id property name to null the identifier generator variable if the target paths contain the id
|
||||
final String identifierPropertyName;
|
||||
if ( identifierGenerator != null ) {
|
||||
identifierPropertyName = entityDescriptor.getIdentifierPropertyName();
|
||||
}
|
||||
else {
|
||||
identifierPropertyName = null;
|
||||
}
|
||||
InMemoryGenerator identifierGenerator = entityDescriptor.getGenerator();
|
||||
identifierPropertyName = identifierGenerator != null ? entityDescriptor.getIdentifierPropertyName() : null;
|
||||
final String versionAttributeName;
|
||||
boolean needsVersionInsert;
|
||||
if ( entityDescriptor.isVersioned() ) {
|
||||
|
@ -1351,7 +1346,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
public static class AdditionalInsertValues {
|
||||
private final Expression versionExpression;
|
||||
private final Expression discriminatorExpression;
|
||||
private final IdentifierGenerator identifierGenerator;
|
||||
private final InMemoryGenerator identifierGenerator;
|
||||
private final BasicEntityIdentifierMapping identifierMapping;
|
||||
private Expression identifierGeneratorParameter;
|
||||
private SqlSelection versionSelection;
|
||||
|
@ -1361,7 +1356,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
public AdditionalInsertValues(
|
||||
Expression versionExpression,
|
||||
Expression discriminatorExpression,
|
||||
IdentifierGenerator identifierGenerator,
|
||||
InMemoryGenerator identifierGenerator,
|
||||
BasicEntityIdentifierMapping identifierMapping) {
|
||||
this.versionExpression = versionExpression;
|
||||
this.discriminatorExpression = discriminatorExpression;
|
||||
|
@ -1453,9 +1448,9 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
|
||||
private static class IdGeneratorParameter extends AbstractJdbcParameter {
|
||||
|
||||
private final IdentifierGenerator generator;
|
||||
private final InMemoryGenerator generator;
|
||||
|
||||
public IdGeneratorParameter(BasicEntityIdentifierMapping identifierMapping, IdentifierGenerator generator) {
|
||||
public IdGeneratorParameter(BasicEntityIdentifierMapping identifierMapping, InMemoryGenerator generator) {
|
||||
super( identifierMapping.getJdbcMapping() );
|
||||
this.generator = generator;
|
||||
}
|
||||
|
@ -1468,7 +1463,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
ExecutionContext executionContext) throws SQLException {
|
||||
getJdbcMapping().getJdbcValueBinder().bind(
|
||||
statement,
|
||||
generator.generate( executionContext.getSession(), null ),
|
||||
generator.generate( executionContext.getSession(), null, null ),
|
||||
startPosition,
|
||||
executionContext.getSession()
|
||||
);
|
||||
|
|
|
@ -11,18 +11,22 @@ import java.lang.reflect.Member;
|
|||
|
||||
|
||||
/**
|
||||
* A {@link Generator} based on a custom Java generator annotation type.
|
||||
* Every instance must implement either {@link InMemoryGenerator} or
|
||||
* {@link InDatabaseGenerator}. Implementing this interface is just a
|
||||
* slightly more typesafe alternative to providing a constructor with
|
||||
* the same signature as the method
|
||||
* {@link #initialize(Annotation, Member, GeneratorCreationContext)}.
|
||||
* A {@link Generator} which receives parameters from a custom
|
||||
* {@linkplain org.hibernate.annotations.ValueGenerationType generator annotation} or
|
||||
* {@linkplain org.hibernate.annotations.IdGeneratorType id generator annotation}.
|
||||
* <p>
|
||||
* Implementing this interface is the same as providing a constructor with the same
|
||||
* signature as the {@link #initialize} method. But implementing this interface is
|
||||
* slightly more typesafe.
|
||||
* <p>
|
||||
* Every instance of this class must implement either {@link InMemoryGenerator} or
|
||||
* {@link InDatabaseGenerator}.
|
||||
*
|
||||
* @param <A> The generator annotation type supported by an implementation
|
||||
*
|
||||
* @see org.hibernate.annotations.ValueGenerationType
|
||||
* @see org.hibernate.annotations.IdGeneratorType
|
||||
*
|
||||
* @author Gunnar Morling
|
||||
* @author Gavin King
|
||||
*
|
||||
* @since 6.2
|
||||
|
@ -31,8 +35,9 @@ public interface AnnotationBasedGenerator<A extends Annotation> extends Generato
|
|||
/**
|
||||
* 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 member the Java member annotated with the generator annotation.
|
||||
* @param context a {@link GeneratorCreationContext}
|
||||
* @throws org.hibernate.HibernateException in case an error occurred during initialization, e.g. if
|
||||
|
|
|
@ -15,23 +15,29 @@ import java.lang.reflect.Method;
|
|||
|
||||
|
||||
/**
|
||||
* A {@link ValueGeneration} based on a custom Java generator annotation type.
|
||||
* An implementation of {@link ValueGeneration} which receives parameters from a custom
|
||||
* {@linkplain org.hibernate.annotations.ValueGenerationType generator annotation}.
|
||||
* <p>
|
||||
* This is an older API that predates {@link Generator} and {@link AnnotationBasedGenerator}.
|
||||
* It's often cleaner to implement {@code AnnotationBasedGenerator} directly.
|
||||
*
|
||||
* @param <A> The generator annotation type supported by an implementation
|
||||
*
|
||||
* @see org.hibernate.annotations.ValueGenerationType
|
||||
*
|
||||
* @author Gunnar Morling
|
||||
*
|
||||
* @see ValueGeneration
|
||||
*/
|
||||
public interface AnnotationValueGeneration<A extends Annotation>
|
||||
extends ValueGeneration, AnnotationBasedGenerator<A> {
|
||||
/**
|
||||
* 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 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.
|
||||
* @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.
|
||||
*/
|
||||
|
|
|
@ -6,15 +6,18 @@
|
|||
*/
|
||||
package org.hibernate.tuple;
|
||||
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
|
||||
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. Every instance must implement either
|
||||
* {@link InMemoryGenerator} or {@link InDatabaseGenerator}
|
||||
* depending on whether values are generated in Java code, or by the database.
|
||||
* {@link InMemoryGenerator} or {@link InDatabaseGenerator} depending on whether values are
|
||||
* generated in Java code, or by the database.
|
||||
* <ul>
|
||||
* <li>Java value generation is the responsibility of an associated {@link ValueGenerator}.
|
||||
* <li>Value generation via arbitrary code written in Java is the responsibility of the method
|
||||
* {@link InMemoryGenerator#generate(SharedSessionContractImplementor, Object, Object)}.
|
||||
* In this case, the generated value is written to the database just like any other field
|
||||
* or property value.
|
||||
* <li>A value generated by the database might be generated implicitly, by a trigger, or using
|
||||
|
@ -23,11 +26,21 @@ import java.io.Serializable;
|
|||
* statement. In this case, the generated value is retrieved from the database using a SQL
|
||||
* {@code select}.
|
||||
* </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 AnnotationBasedGenerator}.
|
||||
* A generator may receive parameters from {@linkplain org.hibernate.annotations.ValueGenerationType
|
||||
* an annotation}. The generator may either:
|
||||
* <ul>
|
||||
* <li>implement {@link AnnotationBasedGenerator}, and receive the annotation as an argument to
|
||||
* {@link AnnotationBasedGenerator#initialize},
|
||||
* <li>declare a constructor with the same signature as {@link AnnotationBasedGenerator#initialize},
|
||||
* <li>declare a constructor which accepts just the annotation instance, or
|
||||
* <li>declare a only default constructor, in which case it will not receive parameters.
|
||||
* </ul>
|
||||
* On the other hand, there is some special machinery for configuring the much older interface
|
||||
* {@link org.hibernate.id.IdentifierGenerator}. But this machinery is only available for
|
||||
* identifier generation.
|
||||
*
|
||||
* @see org.hibernate.annotations.ValueGenerationType
|
||||
* @see org.hibernate.annotations.IdGeneratorType
|
||||
* @see org.hibernate.annotations.Generated
|
||||
* @see org.hibernate.annotations.GeneratorType
|
||||
*
|
||||
|
|
|
@ -16,8 +16,11 @@ public interface IdentifierAttribute extends Attribute {
|
|||
|
||||
boolean isEmbedded();
|
||||
|
||||
@Deprecated
|
||||
IdentifierGenerator getIdentifierGenerator();
|
||||
|
||||
InMemoryGenerator getGenerator();
|
||||
|
||||
boolean isIdentifierAssignedByInsert();
|
||||
|
||||
boolean hasIdentifierMapper();
|
||||
|
|
|
@ -20,7 +20,7 @@ public class IdentifierProperty extends AbstractAttribute implements IdentifierA
|
|||
|
||||
private final boolean virtual;
|
||||
private final boolean embedded;
|
||||
private final IdentifierGenerator identifierGenerator;
|
||||
private final InMemoryGenerator identifierGenerator;
|
||||
private final boolean identifierAssignedByInsert;
|
||||
private final boolean hasIdentifierMapper;
|
||||
|
||||
|
@ -38,7 +38,7 @@ public class IdentifierProperty extends AbstractAttribute implements IdentifierA
|
|||
String name,
|
||||
Type type,
|
||||
boolean embedded,
|
||||
IdentifierGenerator identifierGenerator) {
|
||||
InMemoryGenerator identifierGenerator) {
|
||||
super( name, type );
|
||||
this.virtual = false;
|
||||
this.embedded = embedded;
|
||||
|
@ -59,7 +59,7 @@ public class IdentifierProperty extends AbstractAttribute implements IdentifierA
|
|||
Type type,
|
||||
boolean embedded,
|
||||
boolean hasIdentifierMapper,
|
||||
IdentifierGenerator identifierGenerator) {
|
||||
InMemoryGenerator identifierGenerator) {
|
||||
super( null, type );
|
||||
this.virtual = true;
|
||||
this.embedded = embedded;
|
||||
|
@ -80,6 +80,11 @@ public class IdentifierProperty extends AbstractAttribute implements IdentifierA
|
|||
|
||||
@Override
|
||||
public IdentifierGenerator getIdentifierGenerator() {
|
||||
return (IdentifierGenerator) identifierGenerator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InMemoryGenerator getGenerator() {
|
||||
return identifierGenerator;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,10 @@ import org.hibernate.dialect.Dialect;
|
|||
* 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}.
|
||||
* <p>
|
||||
* Implementations should override {@link #referenceColumnsInSql()},
|
||||
* {@link #writePropertyValue()}, and {@link #getReferencedColumnValues(Dialect)} as needed
|
||||
* in order to achieve the desired behavior.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*
|
||||
|
@ -22,9 +26,9 @@ import org.hibernate.dialect.Dialect;
|
|||
public interface InDatabaseGenerator extends Generator {
|
||||
|
||||
/**
|
||||
* Determines if the columns whose values are generated are included in the column list of
|
||||
* the SQL {@code insert} or {@code update} statement, in the case where the value is
|
||||
* generated by the database. For example, this method should return:
|
||||
* Determines if the columns whose values are generated are included in the column list
|
||||
* of the SQL {@code insert} or {@code update} statement. For example, this method should
|
||||
* return:
|
||||
* <ul>
|
||||
* <li>{@code true} if the value is generated by calling a SQL function like
|
||||
* {@code current_timestamp}, or
|
||||
|
@ -32,10 +36,6 @@ public interface InDatabaseGenerator extends Generator {
|
|||
* by {@link org.hibernate.annotations.GeneratedColumn generated always as}, or
|
||||
* using a {@linkplain org.hibernate.annotations.ColumnDefault column default value}.
|
||||
* </ul>
|
||||
* If the value is generated in Java, this method is not called, and so for backward
|
||||
* compatibility with Hibernate 5 it is permitted to return any value. On the other hand,
|
||||
* when a property value is generated in Java, the column certainly must be included in
|
||||
* the column list, and so it's most correct for this method to return {@code true}!
|
||||
*
|
||||
* @return {@code true} if the column is included in the column list of the SQL statement.
|
||||
*/
|
||||
|
@ -48,18 +48,16 @@ public interface InDatabaseGenerator extends Generator {
|
|||
boolean writePropertyValue();
|
||||
|
||||
/**
|
||||
* A SQL expression indicating how to calculate the generated values when the property values
|
||||
* are {@linkplain #generatedByDatabase() generated in the database} and the mapped columns
|
||||
* A SQL expression indicating how to calculate the generated values when the mapped columns
|
||||
* are {@linkplain #referenceColumnsInSql() included in the SQL statement}. The SQL expressions
|
||||
* might be:
|
||||
* <ul>
|
||||
* <li>function calls like {@code current_timestamp} or {@code nextval('mysequence')}, or
|
||||
* <li>syntactic markers like {@code default}.
|
||||
* </ul>
|
||||
* When the property values are generated in Java, this method is not called.
|
||||
*
|
||||
* @param dialect The {@linkplain Dialect SQL dialect}, allowing generation of an expression
|
||||
* in dialect-specific SQL.
|
||||
* in dialect-specific SQL.
|
||||
* @return The column value to be used in the generated SQL statement.
|
||||
*/
|
||||
String[] getReferencedColumnValues(Dialect dialect);
|
||||
|
|
|
@ -9,9 +9,16 @@ package org.hibernate.tuple;
|
|||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* A generator that is called to produce a value just before a row is written to the database.
|
||||
* The {@link #generate} method may execute arbitrary Java code, it may even, in principle,
|
||||
* access the database via JDBC. But however it is produced, the generated value is sent to the
|
||||
* database via a parameter of a JDBC prepared statement, just like any other field or property
|
||||
* value.
|
||||
* <p>
|
||||
* Any {@link InMemoryGenerator} may be used to produce {@linkplain jakarta.persistence.Id
|
||||
* identifiers}. The built-in identifier generators all implement the older extension point
|
||||
* {@link org.hibernate.id.IdentifierGenerator}, which is a subtype of this interface, but that
|
||||
* is no longer a requirement for custom id generators.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*
|
||||
|
|
|
@ -11,7 +11,6 @@ import org.hibernate.boot.spi.MetadataImplementor;
|
|||
import org.hibernate.boot.spi.SessionFactoryOptions;
|
||||
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementHelper;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||
|
@ -44,7 +43,7 @@ public final class PropertyFactory {
|
|||
*/
|
||||
public static IdentifierProperty buildIdentifierAttribute(
|
||||
PersistentClass mappedEntity,
|
||||
IdentifierGenerator generator) {
|
||||
InMemoryGenerator generator) {
|
||||
Type type = mappedEntity.getIdentifier().getType();
|
||||
Property property = mappedEntity.getIdentifierProperty();
|
||||
|
||||
|
|
|
@ -11,11 +11,15 @@ import org.hibernate.dialect.Dialect;
|
|||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
|
||||
/**
|
||||
* A value generator that can adapt to both Java value generation and database value
|
||||
* generation.
|
||||
* A value generator that can adapt to both Java value generation and database value generation.
|
||||
* <p>
|
||||
* This is an older API that predates {@link Generator}. It's often cleaner to implement either
|
||||
* {@link InMemoryGenerator} or {@link InDatabaseGenerator} directly.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Gavin King
|
||||
*
|
||||
* @see AnnotationValueGeneration
|
||||
*/
|
||||
public interface ValueGeneration extends InMemoryGenerator, InDatabaseGenerator {
|
||||
/**
|
||||
|
|
|
@ -158,7 +158,7 @@ public class EntityMetamodel implements Serializable {
|
|||
|
||||
identifierAttribute = PropertyFactory.buildIdentifierAttribute(
|
||||
persistentClass,
|
||||
sessionFactory.getIdentifierGenerator( rootName )
|
||||
sessionFactory.getGenerator( rootName )
|
||||
);
|
||||
|
||||
versioned = persistentClass.isVersioned();
|
||||
|
|
|
@ -37,10 +37,8 @@ import org.hibernate.engine.spi.SessionImplementor;
|
|||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
|
@ -36,9 +36,9 @@ public class BasicForcedTableSequenceTest {
|
|||
final EntityPersister persister = scope.getSessionFactory()
|
||||
.getMappingMetamodel()
|
||||
.getEntityDescriptor(Entity.class.getName());
|
||||
assertThat( persister.getIdentifierGenerator(), instanceOf( SequenceStyleGenerator.class ) );
|
||||
assertThat( persister.getGenerator(), instanceOf( SequenceStyleGenerator.class ) );
|
||||
|
||||
final SequenceStyleGenerator generator = ( SequenceStyleGenerator ) persister.getIdentifierGenerator();
|
||||
final SequenceStyleGenerator generator = (SequenceStyleGenerator) persister.getGenerator();
|
||||
assertThat( generator.getDatabaseStructure(), instanceOf( TableStructure.class ) );
|
||||
assertThat( generator.getOptimizer(), instanceOf( NoopOptimizer.class ) );
|
||||
|
||||
|
|
|
@ -40,9 +40,9 @@ public class BasicSequenceTest {
|
|||
final EntityPersister persister = scope.getSessionFactory()
|
||||
.getMappingMetamodel()
|
||||
.getEntityDescriptor(Entity.class.getName());
|
||||
assertThat( persister.getIdentifierGenerator(), instanceOf( SequenceStyleGenerator.class ) );
|
||||
assertThat( persister.getGenerator(), instanceOf( SequenceStyleGenerator.class ) );
|
||||
|
||||
final SequenceStyleGenerator generator = (SequenceStyleGenerator) persister.getIdentifierGenerator();
|
||||
final SequenceStyleGenerator generator = (SequenceStyleGenerator) persister.getGenerator();
|
||||
|
||||
final int count = 5;
|
||||
|
||||
|
@ -71,9 +71,9 @@ public class BasicSequenceTest {
|
|||
final EntityPersister persister = scope.getSessionFactory()
|
||||
.getMappingMetamodel()
|
||||
.getEntityDescriptor(overriddenEntityName);
|
||||
assertThat( persister.getIdentifierGenerator(), instanceOf( SequenceStyleGenerator.class ) );
|
||||
assertThat( persister.getGenerator(), instanceOf( SequenceStyleGenerator.class ) );
|
||||
|
||||
final SequenceStyleGenerator generator = (SequenceStyleGenerator) persister.getIdentifierGenerator();
|
||||
final SequenceStyleGenerator generator = (SequenceStyleGenerator) persister.getGenerator();
|
||||
assertEquals( "ID_SEQ_BSC_ENTITY" + SequenceStyleGenerator.DEF_SEQUENCE_SUFFIX,
|
||||
generator.getDatabaseStructure().getPhysicalName().render() );
|
||||
|
||||
|
|
|
@ -29,9 +29,9 @@ public class BasicTableTest {
|
|||
final EntityPersister persister = scope.getSessionFactory()
|
||||
.getMappingMetamodel()
|
||||
.getEntityDescriptor(Entity.class.getName());
|
||||
assertThat( persister.getIdentifierGenerator(), instanceOf( TableGenerator.class ) );
|
||||
assertThat( persister.getGenerator(), instanceOf( TableGenerator.class ) );
|
||||
|
||||
final TableGenerator generator = ( TableGenerator ) persister.getIdentifierGenerator();
|
||||
final TableGenerator generator = ( TableGenerator ) persister.getGenerator();
|
||||
|
||||
scope.inTransaction(
|
||||
(s) -> {
|
||||
|
|
|
@ -39,7 +39,6 @@ import org.hibernate.resource.beans.container.spi.BeanContainer;
|
|||
import org.hibernate.resource.beans.container.spi.BeanContainer.LifecycleOptions;
|
||||
import org.hibernate.resource.beans.container.spi.ContainedBean;
|
||||
import org.hibernate.resource.beans.internal.FallbackBeanInstanceProducer;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.BaseUnitTest;
|
||||
|
||||
|
|
Loading…
Reference in New Issue