clarify some logic around @GeneratedValue
This commit is contained in:
parent
91eb9e1f20
commit
c70d9853c7
|
@ -95,22 +95,27 @@ public class IdGeneratorInterpreterImpl implements IdGeneratorStrategyInterprete
|
||||||
case TABLE:
|
case TABLE:
|
||||||
return org.hibernate.id.enhanced.TableGenerator.class.getName();
|
return org.hibernate.id.enhanced.TableGenerator.class.getName();
|
||||||
case AUTO:
|
case AUTO:
|
||||||
if ( "increment".equalsIgnoreCase( context.getGeneratedValueGeneratorName() ) ) {
|
if ( UUID.class.isAssignableFrom( context.getIdType() ) ) {
|
||||||
return IncrementGenerator.class.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
final Class<?> javaType = context.getIdType();
|
|
||||||
if ( UUID.class.isAssignableFrom( javaType ) ) {
|
|
||||||
return UUIDGenerator.class.getName();
|
return UUIDGenerator.class.getName();
|
||||||
}
|
}
|
||||||
|
else if ( "increment".equalsIgnoreCase( context.getGeneratedValueGeneratorName() ) ) {
|
||||||
return SequenceStyleGenerator.class.getName();
|
// special case for @GeneratedValue(name="increment")
|
||||||
|
// for some reason we consider there to be an implicit
|
||||||
|
// generator named 'increment' (doesn't seem very useful)
|
||||||
|
return IncrementGenerator.class.getName();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return SequenceStyleGenerator.class.getName();
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
// UNKNOWN
|
//case UUID:
|
||||||
|
// (use the name instead for compatibility with javax.persistence)
|
||||||
if ( "UUID".equals( generationType.name() ) ) {
|
if ( "UUID".equals( generationType.name() ) ) {
|
||||||
return UUIDGenerator.class.getName();
|
return UUIDGenerator.class.getName();
|
||||||
}
|
}
|
||||||
throw new UnsupportedOperationException( "Unsupported generation type:" + generationType );
|
else {
|
||||||
|
throw new UnsupportedOperationException( "Unsupported generation type:" + generationType );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,10 @@ import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.hibernate.AnnotationException;
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.Internal;
|
import org.hibernate.Internal;
|
||||||
|
import org.hibernate.boot.model.IdGeneratorStrategyInterpreter.GeneratorNameDeterminationContext;
|
||||||
import org.hibernate.id.IdentifierGenerator;
|
import org.hibernate.id.IdentifierGenerator;
|
||||||
|
|
||||||
import jakarta.persistence.GenerationType;
|
import jakarta.persistence.GenerationType;
|
||||||
|
@ -109,12 +111,14 @@ public class IdentifierGeneratorDefinition implements Serializable {
|
||||||
return buildTableGeneratorDefinition( name, generationInterpreter );
|
return buildTableGeneratorDefinition( name, generationInterpreter );
|
||||||
// really AUTO and IDENTITY work the same in this respect, aside from the actual strategy name
|
// really AUTO and IDENTITY work the same in this respect, aside from the actual strategy name
|
||||||
case IDENTITY:
|
case IDENTITY:
|
||||||
strategyName = "identity";
|
throw new AnnotationException(
|
||||||
break;
|
"@GeneratedValue annotation specified 'strategy=IDENTITY' and 'generator'"
|
||||||
|
+ " but the generator name is unnecessary"
|
||||||
|
);
|
||||||
case AUTO:
|
case AUTO:
|
||||||
strategyName = generationInterpreter.determineGeneratorName(
|
strategyName = generationInterpreter.determineGeneratorName(
|
||||||
generationType,
|
generationType,
|
||||||
new IdGeneratorStrategyInterpreter.GeneratorNameDeterminationContext() {
|
new GeneratorNameDeterminationContext() {
|
||||||
@Override
|
@Override
|
||||||
public Class<?> getIdType() {
|
public Class<?> getIdType() {
|
||||||
return idType;
|
return idType;
|
||||||
|
@ -127,7 +131,17 @@ public class IdentifierGeneratorDefinition implements Serializable {
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new AssertionFailure( "unknown generator type: " + generationType );
|
//case UUID:
|
||||||
|
// (use the name instead for compatibility with javax.persistence)
|
||||||
|
if ( "UUID".equals( generationType.name() ) ) {
|
||||||
|
throw new AnnotationException(
|
||||||
|
"@GeneratedValue annotation specified 'strategy=UUID' and 'generator'"
|
||||||
|
+ " but the generator name is unnecessary"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new AssertionFailure( "unknown generator type: " + generationType );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new IdentifierGeneratorDefinition(
|
return new IdentifierGeneratorDefinition(
|
||||||
|
@ -137,7 +151,8 @@ public class IdentifierGeneratorDefinition implements Serializable {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IdentifierGeneratorDefinition buildTableGeneratorDefinition(String name, IdGeneratorStrategyInterpreter generationInterpreter) {
|
private static IdentifierGeneratorDefinition buildTableGeneratorDefinition(
|
||||||
|
String name, IdGeneratorStrategyInterpreter generationInterpreter) {
|
||||||
final Builder builder = new Builder();
|
final Builder builder = new Builder();
|
||||||
generationInterpreter.interpretTableGenerator(
|
generationInterpreter.interpretTableGenerator(
|
||||||
new TableGenerator() {
|
new TableGenerator() {
|
||||||
|
@ -207,7 +222,8 @@ public class IdentifierGeneratorDefinition implements Serializable {
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IdentifierGeneratorDefinition buildSequenceGeneratorDefinition(String name, IdGeneratorStrategyInterpreter generationInterpreter) {
|
private static IdentifierGeneratorDefinition buildSequenceGeneratorDefinition(
|
||||||
|
String name, IdGeneratorStrategyInterpreter generationInterpreter) {
|
||||||
final Builder builder = new Builder();
|
final Builder builder = new Builder();
|
||||||
generationInterpreter.interpretSequenceGenerator(
|
generationInterpreter.interpretSequenceGenerator(
|
||||||
new SequenceGenerator() {
|
new SequenceGenerator() {
|
||||||
|
|
|
@ -142,7 +142,7 @@ public class GeneratorBinder {
|
||||||
|
|
||||||
private static IdentifierGeneratorDefinition makeIdentifierGeneratorDefinition(
|
private static IdentifierGeneratorDefinition makeIdentifierGeneratorDefinition(
|
||||||
String name,
|
String name,
|
||||||
XProperty idXProperty,
|
XProperty idProperty,
|
||||||
Map<String, IdentifierGeneratorDefinition> localGenerators,
|
Map<String, IdentifierGeneratorDefinition> localGenerators,
|
||||||
MetadataBuildingContext buildingContext) {
|
MetadataBuildingContext buildingContext) {
|
||||||
if ( localGenerators != null ) {
|
if ( localGenerators != null ) {
|
||||||
|
@ -160,7 +160,7 @@ public class GeneratorBinder {
|
||||||
|
|
||||||
LOG.debugf( "Could not resolve explicit IdentifierGeneratorDefinition - using implicit interpretation (%s)", name );
|
LOG.debugf( "Could not resolve explicit IdentifierGeneratorDefinition - using implicit interpretation (%s)", name );
|
||||||
|
|
||||||
final GeneratedValue generatedValue = idXProperty.getAnnotation( GeneratedValue.class );
|
final GeneratedValue generatedValue = idProperty.getAnnotation( GeneratedValue.class );
|
||||||
if ( generatedValue == null ) {
|
if ( generatedValue == null ) {
|
||||||
// this should really never happen, but it's easy to protect against it...
|
// this should really never happen, but it's easy to protect against it...
|
||||||
return new IdentifierGeneratorDefinition( DEFAULT_ID_GEN_STRATEGY, DEFAULT_ID_GEN_STRATEGY );
|
return new IdentifierGeneratorDefinition( DEFAULT_ID_GEN_STRATEGY, DEFAULT_ID_GEN_STRATEGY );
|
||||||
|
@ -171,7 +171,7 @@ public class GeneratorBinder {
|
||||||
buildingContext
|
buildingContext
|
||||||
.getBootstrapContext()
|
.getBootstrapContext()
|
||||||
.getReflectionManager()
|
.getReflectionManager()
|
||||||
.toClass( idXProperty.getType() ),
|
.toClass( idProperty.getType() ),
|
||||||
generatedValue.generator(),
|
generatedValue.generator(),
|
||||||
buildingContext.getBuildingOptions().getIdGenerationTypeInterpreter(),
|
buildingContext.getBuildingOptions().getIdGenerationTypeInterpreter(),
|
||||||
interpretGenerationType( generatedValue )
|
interpretGenerationType( generatedValue )
|
||||||
|
|
|
@ -40,7 +40,6 @@ import java.util.TimeZone;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.hibernate.AssertionFailure;
|
|
||||||
import org.hibernate.Incubating;
|
import org.hibernate.Incubating;
|
||||||
import org.hibernate.Length;
|
import org.hibernate.Length;
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
|
@ -1740,35 +1739,12 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
||||||
|
|
||||||
|
|
||||||
// native identifier generation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// native identifier generation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
/**
|
|
||||||
* The "native" id generation strategy for this dialect.
|
|
||||||
* <p>
|
|
||||||
* This is the id generation strategy which should be used when {@code "native"} is
|
|
||||||
* specified in {@code hbm.xml}, or {@link GenerationType#AUTO} is specified by the
|
|
||||||
* {@link jakarta.persistence.GeneratedValue#strategy @GeneratedValue} annotation.
|
|
||||||
*
|
|
||||||
* @return The native generator strategy.
|
|
||||||
*/
|
|
||||||
@Incubating
|
|
||||||
public GenerationType getNativeIdentifierGenerationType() {
|
|
||||||
switch ( getNativeIdentifierGeneratorStrategy() ) {
|
|
||||||
case "identity":
|
|
||||||
return GenerationType.IDENTITY;
|
|
||||||
case "sequence":
|
|
||||||
return GenerationType.SEQUENCE;
|
|
||||||
case "uuid":
|
|
||||||
return GenerationType.UUID;
|
|
||||||
default:
|
|
||||||
throw new AssertionFailure( "unknown native generation type" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* The name identifying the "native" id generation strategy for this dialect.
|
* The name identifying the "native" id generation strategy for this dialect.
|
||||||
* <p>
|
* <p>
|
||||||
* This is the id generation strategy which should be used when {@code "native"} is
|
* This is the name of the id generation strategy which should be used when
|
||||||
* specified in {@code hbm.xml}, or {@link GenerationType#AUTO} is specified by the
|
* {@code "native"} is specified in {@code hbm.xml}.
|
||||||
* {@link jakarta.persistence.GeneratedValue#strategy @GeneratedValue} annotation.
|
|
||||||
*
|
*
|
||||||
* @return The name identifying the native generator strategy.
|
* @return The name identifying the native generator strategy.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -352,12 +352,6 @@ public class DialectDelegateWrapper extends Dialect {
|
||||||
return wrapped.getLobMergeStrategy();
|
return wrapped.getLobMergeStrategy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@Incubating
|
|
||||||
public GenerationType getNativeIdentifierGenerationType() {
|
|
||||||
return wrapped.getNativeIdentifierGenerationType();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getNativeIdentifierGeneratorStrategy() {
|
public String getNativeIdentifierGeneratorStrategy() {
|
||||||
return wrapped.getNativeIdentifierGeneratorStrategy();
|
return wrapped.getNativeIdentifierGeneratorStrategy();
|
||||||
|
|
|
@ -36,7 +36,6 @@ import org.hibernate.id.factory.spi.GenerationTypeStrategy;
|
||||||
import org.hibernate.id.factory.spi.GenerationTypeStrategyRegistration;
|
import org.hibernate.id.factory.spi.GenerationTypeStrategyRegistration;
|
||||||
import org.hibernate.id.factory.spi.GeneratorDefinitionResolver;
|
import org.hibernate.id.factory.spi.GeneratorDefinitionResolver;
|
||||||
import org.hibernate.id.factory.spi.StandardGenerator;
|
import org.hibernate.id.factory.spi.StandardGenerator;
|
||||||
import org.hibernate.internal.log.DeprecationLogger;
|
|
||||||
import org.hibernate.jpa.spi.IdentifierGeneratorStrategyProvider;
|
import org.hibernate.jpa.spi.IdentifierGeneratorStrategyProvider;
|
||||||
import org.hibernate.resource.beans.container.spi.BeanContainer;
|
import org.hibernate.resource.beans.container.spi.BeanContainer;
|
||||||
import org.hibernate.resource.beans.internal.FallbackBeanInstanceProducer;
|
import org.hibernate.resource.beans.internal.FallbackBeanInstanceProducer;
|
||||||
|
@ -50,6 +49,7 @@ import jakarta.persistence.GenerationType;
|
||||||
|
|
||||||
import static org.hibernate.cfg.AvailableSettings.IDENTIFIER_GENERATOR_STRATEGY_PROVIDER;
|
import static org.hibernate.cfg.AvailableSettings.IDENTIFIER_GENERATOR_STRATEGY_PROVIDER;
|
||||||
import static org.hibernate.id.factory.IdGenFactoryLogging.ID_GEN_FAC_LOGGER;
|
import static org.hibernate.id.factory.IdGenFactoryLogging.ID_GEN_FAC_LOGGER;
|
||||||
|
import static org.hibernate.internal.log.DeprecationLogger.DEPRECATION_LOGGER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic implementation of {@link org.hibernate.id.factory.IdentifierGeneratorFactory},
|
* Basic implementation of {@link org.hibernate.id.factory.IdentifierGeneratorFactory},
|
||||||
|
@ -151,7 +151,7 @@ public class StandardIdentifierGeneratorFactory
|
||||||
final ConfigurationService configService = serviceRegistry.getService( ConfigurationService.class );
|
final ConfigurationService configService = serviceRegistry.getService( ConfigurationService.class );
|
||||||
final Object providerSetting = configService.getSettings().get( IDENTIFIER_GENERATOR_STRATEGY_PROVIDER );
|
final Object providerSetting = configService.getSettings().get( IDENTIFIER_GENERATOR_STRATEGY_PROVIDER );
|
||||||
if ( providerSetting != null ) {
|
if ( providerSetting != null ) {
|
||||||
DeprecationLogger.DEPRECATION_LOGGER.deprecatedSetting2(
|
DEPRECATION_LOGGER.deprecatedSetting2(
|
||||||
IDENTIFIER_GENERATOR_STRATEGY_PROVIDER,
|
IDENTIFIER_GENERATOR_STRATEGY_PROVIDER,
|
||||||
"supply a org.hibernate.id.factory.spi.GenerationTypeStrategyRegistration Java service"
|
"supply a org.hibernate.id.factory.spi.GenerationTypeStrategyRegistration Java service"
|
||||||
);
|
);
|
||||||
|
@ -243,32 +243,32 @@ public class StandardIdentifierGeneratorFactory
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<? extends Generator> getIdentifierGeneratorClass(String strategy) {
|
public Class<? extends Generator> getIdentifierGeneratorClass(String strategy) {
|
||||||
if ( "hilo".equals( strategy ) ) {
|
switch ( strategy ) {
|
||||||
throw new UnsupportedOperationException( "Support for 'hilo' generator has been removed" );
|
case "hilo":
|
||||||
|
throw new UnsupportedOperationException( "Support for 'hilo' generator has been removed" );
|
||||||
|
case "native":
|
||||||
|
strategy = getDialect().getNativeIdentifierGeneratorStrategy();
|
||||||
|
//then fall through:
|
||||||
|
default:
|
||||||
|
Class<? extends Generator> generatorClass = legacyGeneratorClassNameMap.get( strategy );
|
||||||
|
return generatorClass != null ? generatorClass : generatorClassForName( strategy );
|
||||||
}
|
}
|
||||||
final String resolvedStrategy = "native".equals( strategy )
|
}
|
||||||
? getDialect().getNativeIdentifierGeneratorStrategy()
|
|
||||||
: strategy;
|
|
||||||
|
|
||||||
Class<? extends Generator> generatorClass = legacyGeneratorClassNameMap.get( resolvedStrategy );
|
private Class<? extends Generator> generatorClassForName(String strategy) {
|
||||||
if ( generatorClass != null ) {
|
try {
|
||||||
return generatorClass;
|
Class<? extends Generator> clazz =
|
||||||
|
serviceRegistry.getService( ClassLoaderService.class )
|
||||||
|
.classForName( strategy );
|
||||||
|
if ( !Generator.class.isAssignableFrom( clazz ) ) {
|
||||||
|
// in principle, this shouldn't happen, since @GenericGenerator
|
||||||
|
// constrains the type to subtypes of Generator
|
||||||
|
throw new MappingException( clazz.getName() + " does not implement 'Generator'" );
|
||||||
|
}
|
||||||
|
return clazz;
|
||||||
}
|
}
|
||||||
else {
|
catch ( ClassLoadingException e ) {
|
||||||
try {
|
throw new MappingException( String.format( "Could not interpret id generator strategy [%s]", strategy) );
|
||||||
Class<? extends Generator> clazz =
|
|
||||||
serviceRegistry.getService( ClassLoaderService.class )
|
|
||||||
.classForName( resolvedStrategy );
|
|
||||||
if ( !Generator.class.isAssignableFrom( clazz ) ) {
|
|
||||||
// in principle, this shouldn't happen, since @GenericGenerator
|
|
||||||
// constrains the type to subtypes of Generator
|
|
||||||
throw new MappingException( clazz.getName() + " does not implement 'Generator'" );
|
|
||||||
}
|
|
||||||
return clazz;
|
|
||||||
}
|
|
||||||
catch ( ClassLoadingException e ) {
|
|
||||||
throw new MappingException( String.format( "Could not interpret id generator strategy [%s]", strategy ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue