From 1f50efa34cc3f2fc93b9aebb759f3c972ab7c833 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Thu, 26 Mar 2015 22:53:27 -0500 Subject: [PATCH] HHH-9524 - Make strategy for interpreting id-generator annotations pluggable --- .../org/hibernate/boot/MetadataBuilder.java | 5 +- .../IdGenerationTypeInterpreterImpl.java | 135 ------- .../internal/IdGeneratorInterpreterImpl.java | 339 ++++++++++++++++++ .../boot/internal/MetadataBuilderImpl.java | 17 +- .../model/IdGenerationTypeInterpreter.java | 48 --- .../model/IdGeneratorStrategyInterpreter.java | 67 ++++ .../boot/spi/MetadataBuildingOptions.java | 13 +- .../org/hibernate/cfg/AnnotationBinder.java | 154 ++------ 8 files changed, 447 insertions(+), 331 deletions(-) delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/internal/IdGenerationTypeInterpreterImpl.java create mode 100644 hibernate-core/src/main/java/org/hibernate/boot/internal/IdGeneratorInterpreterImpl.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/boot/model/IdGenerationTypeInterpreter.java create mode 100644 hibernate-core/src/main/java/org/hibernate/boot/model/IdGeneratorStrategyInterpreter.java diff --git a/hibernate-core/src/main/java/org/hibernate/boot/MetadataBuilder.java b/hibernate-core/src/main/java/org/hibernate/boot/MetadataBuilder.java index e0492bf37f..50f72201db 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/MetadataBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/MetadataBuilder.java @@ -23,7 +23,6 @@ */ package org.hibernate.boot; -import java.util.List; import javax.persistence.AttributeConverter; import javax.persistence.SharedCacheMode; @@ -32,7 +31,7 @@ import org.hibernate.boot.archive.scan.spi.ScanEnvironment; import org.hibernate.boot.archive.scan.spi.ScanOptions; import org.hibernate.boot.archive.scan.spi.Scanner; import org.hibernate.boot.archive.spi.ArchiveDescriptorFactory; -import org.hibernate.boot.model.IdGenerationTypeInterpreter; +import org.hibernate.boot.model.IdGeneratorStrategyInterpreter; import org.hibernate.boot.model.TypeContributor; import org.hibernate.boot.model.naming.ImplicitNamingStrategy; import org.hibernate.boot.model.naming.PhysicalNamingStrategy; @@ -398,7 +397,7 @@ public interface MetadataBuilder { */ MetadataBuilder applyAttributeConverter(AttributeConverter attributeConverter, boolean autoApply); - MetadataBuilder applyIdGenerationTypeInterpreter(IdGenerationTypeInterpreter interpreter); + MetadataBuilder applyIdGenerationTypeInterpreter(IdGeneratorStrategyInterpreter interpreter); // /** diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/IdGenerationTypeInterpreterImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/IdGenerationTypeInterpreterImpl.java deleted file mode 100644 index 367b80f8aa..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/IdGenerationTypeInterpreterImpl.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2015, Red Hat Inc. or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Inc. - * - * This copyrighted material is made available to anyone wishing to use, modify, - * copy, or redistribute it subject to the terms and conditions of the GNU - * Lesser General Public License, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this distribution; if not, write to: - * Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301 USA - */ -package org.hibernate.boot.internal; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; -import javax.persistence.GenerationType; - -import org.hibernate.boot.model.IdGenerationTypeInterpreter; -import org.hibernate.id.MultipleHiLoPerTableGenerator; -import org.hibernate.id.UUIDGenerator; - -/** - * The root (composition) IdGenerationTypeInterpreter. - * - * @author Steve Ebersole - */ -public class IdGenerationTypeInterpreterImpl implements IdGenerationTypeInterpreter { - private IdGenerationTypeInterpreter fallbackInterpreter = FallbackInterpreter.INSTANCE; - private ArrayList delegates; - - @Override - public String determineGeneratorName(GenerationType generationType, Context context) { - if ( delegates != null ) { - for ( IdGenerationTypeInterpreter delegate : delegates ) { - final String result = delegate.determineGeneratorName( generationType, context ); - if ( result != null ) { - return result; - } - } - } - return fallbackInterpreter.determineGeneratorName( generationType, context ); - } - - public void enableLegacyFallback() { - fallbackInterpreter = LegacyFallbackInterpreter.INSTANCE; - } - - public void disableLegacyFallback() { - fallbackInterpreter = FallbackInterpreter.INSTANCE; - } - - public void addInterpreterDelegate(IdGenerationTypeInterpreter delegate) { - if ( delegates == null ) { - delegates = new ArrayList(); - } - delegates.add( delegate ); - } - - private static class LegacyFallbackInterpreter implements IdGenerationTypeInterpreter { - /** - * Singleton access - */ - public static final LegacyFallbackInterpreter INSTANCE = new LegacyFallbackInterpreter(); - - @Override - public String determineGeneratorName(GenerationType generationType, Context context) { - switch ( generationType ) { - case IDENTITY: { - return "identity"; - } - case SEQUENCE: { - return "seqhilo"; - } - case TABLE: { - return MultipleHiLoPerTableGenerator.class.getName(); - } - default: { - // AUTO - final Class javaType = context.getIdType(); - if ( UUID.class.isAssignableFrom( javaType ) ) { - return UUIDGenerator.class.getName(); - } - else { - return "native"; - } - } - } - } - } - - private static class FallbackInterpreter implements IdGenerationTypeInterpreter { - /** - * Singleton access - */ - public static final FallbackInterpreter INSTANCE = new FallbackInterpreter(); - - @Override - public String determineGeneratorName(GenerationType generationType, Context context) { - switch ( generationType ) { - case IDENTITY: { - return "identity"; - } - case SEQUENCE: { - return org.hibernate.id.enhanced.SequenceStyleGenerator.class.getName(); - } - case TABLE: { - return org.hibernate.id.enhanced.TableGenerator.class.getName(); - } - default: { - // AUTO - final Class javaType = context.getIdType(); - if ( UUID.class.isAssignableFrom( javaType ) ) { - return UUIDGenerator.class.getName(); - } - else { - return org.hibernate.id.enhanced.SequenceStyleGenerator.class.getName(); - } - } - } - } - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/IdGeneratorInterpreterImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/IdGeneratorInterpreterImpl.java new file mode 100644 index 0000000000..b49207d856 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/IdGeneratorInterpreterImpl.java @@ -0,0 +1,339 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2015, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.boot.internal; + +import java.util.ArrayList; +import java.util.UUID; +import javax.persistence.GenerationType; +import javax.persistence.SequenceGenerator; +import javax.persistence.TableGenerator; + +import org.hibernate.boot.model.IdGeneratorStrategyInterpreter; +import org.hibernate.boot.model.IdentifierGeneratorDefinition; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.cfg.BinderHelper; +import org.hibernate.id.MultipleHiLoPerTableGenerator; +import org.hibernate.id.PersistentIdentifierGenerator; +import org.hibernate.id.SequenceHiLoGenerator; +import org.hibernate.id.UUIDGenerator; +import org.hibernate.id.enhanced.SequenceStyleGenerator; +import org.hibernate.internal.CoreLogging; +import org.hibernate.internal.CoreMessageLogger; + +/** + * The root (composition) IdGenerationTypeInterpreter. + * + * @author Steve Ebersole + */ +public class IdGeneratorInterpreterImpl implements IdGeneratorStrategyInterpreter { + private static final CoreMessageLogger log = CoreLogging.messageLogger( IdGeneratorInterpreterImpl.class ); + + private IdGeneratorStrategyInterpreter fallbackInterpreter = FallbackInterpreter.INSTANCE; + private ArrayList delegates; + + @Override + public String determineGeneratorName(GenerationType generationType, GeneratorNameDeterminationContext context) { + if ( delegates != null ) { + for ( IdGeneratorStrategyInterpreter delegate : delegates ) { + final String result = delegate.determineGeneratorName( generationType, context ); + if ( result != null ) { + return result; + } + } + } + return fallbackInterpreter.determineGeneratorName( generationType, context ); + } + + @Override + public void interpretTableGenerator( + TableGenerator tableGeneratorAnnotation, + IdentifierGeneratorDefinition.Builder definitionBuilder) { + fallbackInterpreter.interpretTableGenerator( tableGeneratorAnnotation, definitionBuilder ); + + if ( delegates != null ) { + for ( IdGeneratorStrategyInterpreter delegate : delegates ) { + delegate.interpretTableGenerator( tableGeneratorAnnotation, definitionBuilder ); + } + } + } + + @Override + public void interpretSequenceGenerator( + SequenceGenerator sequenceGeneratorAnnotation, + IdentifierGeneratorDefinition.Builder definitionBuilder) { + fallbackInterpreter.interpretSequenceGenerator( sequenceGeneratorAnnotation, definitionBuilder ); + + if ( delegates != null ) { + for ( IdGeneratorStrategyInterpreter delegate : delegates ) { + delegate.interpretSequenceGenerator( sequenceGeneratorAnnotation, definitionBuilder ); + } + } + } + + public void enableLegacyFallback() { + fallbackInterpreter = LegacyFallbackInterpreter.INSTANCE; + } + + public void disableLegacyFallback() { + fallbackInterpreter = FallbackInterpreter.INSTANCE; + } + + public void addInterpreterDelegate(IdGeneratorStrategyInterpreter delegate) { + if ( delegates == null ) { + delegates = new ArrayList(); + } + delegates.add( delegate ); + } + + private static class LegacyFallbackInterpreter implements IdGeneratorStrategyInterpreter { + /** + * Singleton access + */ + public static final LegacyFallbackInterpreter INSTANCE = new LegacyFallbackInterpreter(); + + @Override + public String determineGeneratorName(GenerationType generationType, GeneratorNameDeterminationContext context) { + switch ( generationType ) { + case IDENTITY: { + return "identity"; + } + case SEQUENCE: { + return "seqhilo"; + } + case TABLE: { + return MultipleHiLoPerTableGenerator.class.getName(); + } + default: { + // AUTO + final Class javaType = context.getIdType(); + if ( UUID.class.isAssignableFrom( javaType ) ) { + return UUIDGenerator.class.getName(); + } + else { + return "native"; + } + } + } + } + + @Override + public void interpretTableGenerator( + TableGenerator tableGeneratorAnnotation, + IdentifierGeneratorDefinition.Builder definitionBuilder) { + definitionBuilder.setName( tableGeneratorAnnotation.name() ); + definitionBuilder.setStrategy( MultipleHiLoPerTableGenerator.class.getName() ); + + if ( !BinderHelper.isEmptyAnnotationValue( tableGeneratorAnnotation.table() ) ) { + definitionBuilder.addParam( + MultipleHiLoPerTableGenerator.ID_TABLE, + tableGeneratorAnnotation.table() + ); + } + if ( !BinderHelper.isEmptyAnnotationValue( tableGeneratorAnnotation.catalog() ) ) { + definitionBuilder.addParam( + PersistentIdentifierGenerator.CATALOG, + tableGeneratorAnnotation.catalog() + ); + } + if ( !BinderHelper.isEmptyAnnotationValue( tableGeneratorAnnotation.schema() ) ) { + definitionBuilder.addParam( + PersistentIdentifierGenerator.SCHEMA, + tableGeneratorAnnotation.schema() + ); + } + + if ( !BinderHelper.isEmptyAnnotationValue( tableGeneratorAnnotation.pkColumnName() ) ) { + definitionBuilder.addParam( + MultipleHiLoPerTableGenerator.PK_COLUMN_NAME, + tableGeneratorAnnotation.pkColumnName() + ); + } + if ( !BinderHelper.isEmptyAnnotationValue( tableGeneratorAnnotation.valueColumnName() ) ) { + definitionBuilder.addParam( + MultipleHiLoPerTableGenerator.VALUE_COLUMN_NAME, + tableGeneratorAnnotation.valueColumnName() + ); + } + if ( !BinderHelper.isEmptyAnnotationValue( tableGeneratorAnnotation.pkColumnValue() ) ) { + definitionBuilder.addParam( + MultipleHiLoPerTableGenerator.PK_VALUE_NAME, + tableGeneratorAnnotation.pkColumnValue() + ); + } + definitionBuilder.addParam( + MultipleHiLoPerTableGenerator.MAX_LO, + String.valueOf( tableGeneratorAnnotation.allocationSize() - 1 ) + ); + + // TODO : implement unique-constraint support + if ( tableGeneratorAnnotation.uniqueConstraints() != null + && tableGeneratorAnnotation.uniqueConstraints().length > 0 ) { + log.ignoringTableGeneratorConstraints( tableGeneratorAnnotation.name() ); + } + } + + @Override + @SuppressWarnings("deprecation") + public void interpretSequenceGenerator( + SequenceGenerator sequenceGeneratorAnnotation, + IdentifierGeneratorDefinition.Builder definitionBuilder) { + definitionBuilder.setName( sequenceGeneratorAnnotation.name() ); + + definitionBuilder.setStrategy( "seqhilo" ); + + if ( !BinderHelper.isEmptyAnnotationValue( sequenceGeneratorAnnotation.sequenceName() ) ) { + definitionBuilder.addParam( org.hibernate.id.SequenceGenerator.SEQUENCE, sequenceGeneratorAnnotation.sequenceName() ); + } + //FIXME: work on initialValue() through SequenceGenerator.PARAMETERS + // steve : or just use o.h.id.enhanced.SequenceStyleGenerator + if ( sequenceGeneratorAnnotation.initialValue() != 1 ) { + log.unsupportedInitialValue( AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS ); + } + definitionBuilder.addParam( SequenceHiLoGenerator.MAX_LO, String.valueOf( sequenceGeneratorAnnotation.allocationSize() - 1 ) ); + } + } + + private static class FallbackInterpreter implements IdGeneratorStrategyInterpreter { + /** + * Singleton access + */ + public static final FallbackInterpreter INSTANCE = new FallbackInterpreter(); + + @Override + public String determineGeneratorName(GenerationType generationType, GeneratorNameDeterminationContext context) { + switch ( generationType ) { + case IDENTITY: { + return "identity"; + } + case SEQUENCE: { + return org.hibernate.id.enhanced.SequenceStyleGenerator.class.getName(); + } + case TABLE: { + return org.hibernate.id.enhanced.TableGenerator.class.getName(); + } + default: { + // AUTO + final Class javaType = context.getIdType(); + if ( UUID.class.isAssignableFrom( javaType ) ) { + return UUIDGenerator.class.getName(); + } + else { + return org.hibernate.id.enhanced.SequenceStyleGenerator.class.getName(); + } + } + } + } + + @Override + public void interpretTableGenerator( + TableGenerator tableGeneratorAnnotation, + IdentifierGeneratorDefinition.Builder definitionBuilder) { + definitionBuilder.setName( tableGeneratorAnnotation.name() ); + definitionBuilder.setStrategy( org.hibernate.id.enhanced.TableGenerator.class.getName() ); + definitionBuilder.addParam( org.hibernate.id.enhanced.TableGenerator.CONFIG_PREFER_SEGMENT_PER_ENTITY, "true" ); + + if ( !BinderHelper.isEmptyAnnotationValue( tableGeneratorAnnotation.catalog() ) ) { + definitionBuilder.addParam( PersistentIdentifierGenerator.CATALOG, tableGeneratorAnnotation.catalog() ); + } + if ( !BinderHelper.isEmptyAnnotationValue( tableGeneratorAnnotation.schema() ) ) { + definitionBuilder.addParam( PersistentIdentifierGenerator.SCHEMA, tableGeneratorAnnotation.schema() ); + } + if ( !BinderHelper.isEmptyAnnotationValue( tableGeneratorAnnotation.table() ) ) { + definitionBuilder.addParam( + org.hibernate.id.enhanced.TableGenerator.TABLE_PARAM, + tableGeneratorAnnotation.table() + ); + } + if ( !BinderHelper.isEmptyAnnotationValue( tableGeneratorAnnotation.pkColumnName() ) ) { + definitionBuilder.addParam( + org.hibernate.id.enhanced.TableGenerator.SEGMENT_COLUMN_PARAM, + tableGeneratorAnnotation.pkColumnName() + ); + } + if ( !BinderHelper.isEmptyAnnotationValue( tableGeneratorAnnotation.pkColumnValue() ) ) { + definitionBuilder.addParam( + org.hibernate.id.enhanced.TableGenerator.SEGMENT_VALUE_PARAM, + tableGeneratorAnnotation.pkColumnValue() + ); + } + if ( !BinderHelper.isEmptyAnnotationValue( tableGeneratorAnnotation.valueColumnName() ) ) { + definitionBuilder.addParam( + org.hibernate.id.enhanced.TableGenerator.VALUE_COLUMN_PARAM, + tableGeneratorAnnotation.valueColumnName() + ); + } + definitionBuilder.addParam( + org.hibernate.id.enhanced.TableGenerator.INCREMENT_PARAM, + String.valueOf( tableGeneratorAnnotation.allocationSize() ) + ); + // See comment on HHH-4884 wrt initialValue. Basically initialValue is really the stated value + 1 + definitionBuilder.addParam( + org.hibernate.id.enhanced.TableGenerator.INITIAL_PARAM, + String.valueOf( tableGeneratorAnnotation.initialValue() + 1 ) + ); + + // TODO : implement unique-constraint support + if ( tableGeneratorAnnotation.uniqueConstraints() != null + && tableGeneratorAnnotation.uniqueConstraints().length > 0 ) { + log.ignoringTableGeneratorConstraints( tableGeneratorAnnotation.name() ); + } + } + + @Override + public void interpretSequenceGenerator( + SequenceGenerator sequenceGeneratorAnnotation, + IdentifierGeneratorDefinition.Builder definitionBuilder) { + definitionBuilder.setName( sequenceGeneratorAnnotation.name() ); + definitionBuilder.setStrategy( SequenceStyleGenerator.class.getName() ); + + if ( !BinderHelper.isEmptyAnnotationValue( sequenceGeneratorAnnotation.catalog() ) ) { + definitionBuilder.addParam( + PersistentIdentifierGenerator.CATALOG, + sequenceGeneratorAnnotation.catalog() + ); + } + if ( !BinderHelper.isEmptyAnnotationValue( sequenceGeneratorAnnotation.schema() ) ) { + definitionBuilder.addParam( + PersistentIdentifierGenerator.SCHEMA, + sequenceGeneratorAnnotation.schema() + ); + } + if ( !BinderHelper.isEmptyAnnotationValue( sequenceGeneratorAnnotation.sequenceName() ) ) { + definitionBuilder.addParam( + SequenceStyleGenerator.SEQUENCE_PARAM, + sequenceGeneratorAnnotation.sequenceName() + ); + } + + definitionBuilder.addParam( + SequenceStyleGenerator.INCREMENT_PARAM, + String.valueOf( sequenceGeneratorAnnotation.allocationSize() ) + ); + definitionBuilder.addParam( + SequenceStyleGenerator.INITIAL_PARAM, + String.valueOf( sequenceGeneratorAnnotation.initialValue() ) + ); + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataBuilderImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataBuilderImpl.java index 7dd38b40f3..35e91e4135 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataBuilderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataBuilderImpl.java @@ -49,7 +49,7 @@ import org.hibernate.boot.archive.spi.ArchiveDescriptorFactory; import org.hibernate.boot.cfgxml.spi.CfgXmlAccessService; import org.hibernate.boot.cfgxml.spi.LoadedConfig; import org.hibernate.boot.cfgxml.spi.MappingReference; -import org.hibernate.boot.model.IdGenerationTypeInterpreter; +import org.hibernate.boot.model.IdGeneratorStrategyInterpreter; import org.hibernate.boot.model.TypeContributions; import org.hibernate.boot.model.TypeContributor; import org.hibernate.boot.model.naming.ImplicitNamingStrategy; @@ -380,7 +380,6 @@ public class MetadataBuilderImpl implements MetadataBuilder, TypeContributions { @Override public MetadataBuilder enableNewIdentifierGeneratorSupport(boolean enabled) { - this.options.useNewIdentifierGenerators = enabled; if ( enabled ) { this.options.idGenerationTypeInterpreter.disableLegacyFallback(); } @@ -391,7 +390,7 @@ public class MetadataBuilderImpl implements MetadataBuilder, TypeContributions { } @Override - public MetadataBuilder applyIdGenerationTypeInterpreter(IdGenerationTypeInterpreter interpreter) { + public MetadataBuilder applyIdGenerationTypeInterpreter(IdGeneratorStrategyInterpreter interpreter) { this.options.idGenerationTypeInterpreter.addInterpreterDelegate( interpreter ); return this; } @@ -556,8 +555,7 @@ public class MetadataBuilderImpl implements MetadataBuilder, TypeContributions { private ArrayList auxiliaryDatabaseObjectList; private HashMap attributeConverterDefinitionsByClass; - private boolean useNewIdentifierGenerators; - private IdGenerationTypeInterpreterImpl idGenerationTypeInterpreter = new IdGenerationTypeInterpreterImpl(); + private IdGeneratorInterpreterImpl idGenerationTypeInterpreter = new IdGeneratorInterpreterImpl(); private static ReflectionManager generateDefaultReflectionManager() { final JavaReflectionManager reflectionManager = new JavaReflectionManager(); @@ -679,7 +677,7 @@ public class MetadataBuilderImpl implements MetadataBuilder, TypeContributions { sourceProcessOrdering = resolveInitialSourceProcessOrdering( configService ); - useNewIdentifierGenerators = configService.getSetting( + final boolean useNewIdentifierGenerators = configService.getSetting( AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, StandardConverters.BOOLEAN, false @@ -790,12 +788,7 @@ public class MetadataBuilderImpl implements MetadataBuilder, TypeContributions { } @Override - public boolean isUseNewIdentifierGenerators() { - return useNewIdentifierGenerators; - } - - @Override - public IdGenerationTypeInterpreter getIdGenerationTypeInterpreter() { + public IdGeneratorStrategyInterpreter getIdGenerationTypeInterpreter() { return idGenerationTypeInterpreter; } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/IdGenerationTypeInterpreter.java b/hibernate-core/src/main/java/org/hibernate/boot/model/IdGenerationTypeInterpreter.java deleted file mode 100644 index 48aa1bd9ad..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/IdGenerationTypeInterpreter.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2015, Red Hat Inc. or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Inc. - * - * This copyrighted material is made available to anyone wishing to use, modify, - * copy, or redistribute it subject to the terms and conditions of the GNU - * Lesser General Public License, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this distribution; if not, write to: - * Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301 USA - */ -package org.hibernate.boot.model; - -import javax.persistence.GenerationType; - -/** - * Delegate for interpreting the name of the IdentifierGenerator to use based on - * GenerationType. - * - * @author Steve Ebersole - */ -public interface IdGenerationTypeInterpreter { - public static interface Context { - public Class getIdType(); - } - - /** - * Determine the name of the generator which should be used, returning {@code null} to - * indicate that this interpreter did not have a match and that any additional resolutions - * should be performed. - * - * @param generationType The {@link javax.persistence.GeneratedValue#strategy} value - * @param context The context for resolution (method parameter object) - */ - String determineGeneratorName(GenerationType generationType, Context context); -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/IdGeneratorStrategyInterpreter.java b/hibernate-core/src/main/java/org/hibernate/boot/model/IdGeneratorStrategyInterpreter.java new file mode 100644 index 0000000000..60d752e24c --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/IdGeneratorStrategyInterpreter.java @@ -0,0 +1,67 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2015, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.boot.model; + +import javax.persistence.GenerationType; +import javax.persistence.SequenceGenerator; +import javax.persistence.TableGenerator; + +/** + * Strategy for interpreting identifier generator related information. + * + * @author Steve Ebersole + */ +public interface IdGeneratorStrategyInterpreter { + public static interface GeneratorNameDeterminationContext { + public Class getIdType(); + } + + /** + * Determine the name of the generator which should be used based on the + * GenerationType, returning {@code null} to indicate that this interpreter + * did not have a match and that any additional resolutions should be performed. + * + * @param generationType The {@link javax.persistence.GeneratedValue#strategy} value + * @param context The context for resolution (method parameter object) + */ + String determineGeneratorName(GenerationType generationType, GeneratorNameDeterminationContext context); + + /** + * Extract the IdentifierGeneratorDefinition related to the given TableGenerator annotation + * + * @param tableGeneratorAnnotation The annotation + * @param definitionBuilder The IdentifierGeneratorDefinition builder to which to apply + * any interpreted/extracted configuration + */ + void interpretTableGenerator(TableGenerator tableGeneratorAnnotation, IdentifierGeneratorDefinition.Builder definitionBuilder); + + /** + * Extract the IdentifierGeneratorDefinition related to the given SequenceGenerator annotation + * + * @param sequenceGeneratorAnnotation The annotation + * @param definitionBuilder The IdentifierGeneratorDefinition builder to which to apply + * any interpreted/extracted configuration + */ + void interpretSequenceGenerator(SequenceGenerator sequenceGeneratorAnnotation, IdentifierGeneratorDefinition.Builder definitionBuilder); +} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/MetadataBuildingOptions.java b/hibernate-core/src/main/java/org/hibernate/boot/spi/MetadataBuildingOptions.java index a7ccebd929..f5f02f97a3 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/MetadataBuildingOptions.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/spi/MetadataBuildingOptions.java @@ -33,7 +33,7 @@ import org.hibernate.boot.CacheRegionDefinition; import org.hibernate.boot.archive.scan.spi.ScanEnvironment; import org.hibernate.boot.archive.scan.spi.ScanOptions; import org.hibernate.boot.archive.spi.ArchiveDescriptorFactory; -import org.hibernate.boot.model.IdGenerationTypeInterpreter; +import org.hibernate.boot.model.IdGeneratorStrategyInterpreter; import org.hibernate.boot.model.naming.ImplicitNamingStrategy; import org.hibernate.boot.model.naming.PhysicalNamingStrategy; import org.hibernate.boot.model.relational.AuxiliaryDatabaseObject; @@ -155,16 +155,7 @@ public interface MetadataBuildingOptions { */ MultiTenancyStrategy getMultiTenancyStrategy(); - /** - * Access to whether we should be using the new identifier generator scheme. - * {@code true} indicates to use the new schema, {@code false} indicates to use the - * legacy scheme. - * - * @return Whether to use the new identifier generator scheme - */ - boolean isUseNewIdentifierGenerators(); - - IdGenerationTypeInterpreter getIdGenerationTypeInterpreter(); + IdGeneratorStrategyInterpreter getIdGenerationTypeInterpreter(); /** * Access to all explicit cache region mappings. diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java index 7a8b09f5c9..41955ede13 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java @@ -36,7 +36,6 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; -import java.util.UUID; import javax.persistence.Basic; import javax.persistence.Cacheable; import javax.persistence.CollectionTable; @@ -145,7 +144,7 @@ import org.hibernate.annotations.common.reflection.XClass; import org.hibernate.annotations.common.reflection.XMethod; import org.hibernate.annotations.common.reflection.XPackage; import org.hibernate.annotations.common.reflection.XProperty; -import org.hibernate.boot.model.IdGenerationTypeInterpreter; +import org.hibernate.boot.model.IdGeneratorStrategyInterpreter; import org.hibernate.boot.model.IdentifierGeneratorDefinition; import org.hibernate.boot.model.TypeDefinition; import org.hibernate.boot.spi.InFlightMetadataCollector.EntityTableXref; @@ -161,11 +160,7 @@ import org.hibernate.cfg.annotations.SimpleValueBinder; import org.hibernate.cfg.annotations.TableBinder; import org.hibernate.engine.OptimisticLockStyle; import org.hibernate.engine.spi.FilterDefinition; -import org.hibernate.id.MultipleHiLoPerTableGenerator; import org.hibernate.id.PersistentIdentifierGenerator; -import org.hibernate.id.SequenceHiLoGenerator; -import org.hibernate.id.UUIDGenerator; -import org.hibernate.id.enhanced.SequenceStyleGenerator; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.util.StringHelper; import org.hibernate.loader.PropertyPath; @@ -437,146 +432,61 @@ public final class AnnotationBinder { } private static IdentifierGeneratorDefinition buildIdGenerator(java.lang.annotation.Annotation ann, MetadataBuildingContext context) { - IdentifierGeneratorDefinition.Builder idGen = new IdentifierGeneratorDefinition.Builder(); + if ( ann == null ) { + return null; + } + + IdentifierGeneratorDefinition.Builder definitionBuilder = new IdentifierGeneratorDefinition.Builder(); if ( context.getMappingDefaults().getImplicitSchemaName() != null ) { - idGen.addParam( PersistentIdentifierGenerator.SCHEMA, context.getMappingDefaults().getImplicitSchemaName() ); + definitionBuilder.addParam( + PersistentIdentifierGenerator.SCHEMA, + context.getMappingDefaults().getImplicitSchemaName() + ); } if ( context.getMappingDefaults().getImplicitCatalogName() != null ) { - idGen.addParam( PersistentIdentifierGenerator.CATALOG, context.getMappingDefaults().getImplicitCatalogName() ); + definitionBuilder.addParam( + PersistentIdentifierGenerator.CATALOG, + context.getMappingDefaults().getImplicitCatalogName() + ); } - final boolean useNewGeneratorMappings = context.getBuildingOptions().isUseNewIdentifierGenerators(); - if ( ann == null ) { - idGen = null; - } - else if ( ann instanceof TableGenerator ) { - TableGenerator tabGen = ( TableGenerator ) ann; - idGen.setName( tabGen.name() ); - if ( useNewGeneratorMappings ) { - idGen.setStrategy( org.hibernate.id.enhanced.TableGenerator.class.getName() ); - idGen.addParam( org.hibernate.id.enhanced.TableGenerator.CONFIG_PREFER_SEGMENT_PER_ENTITY, "true" ); - - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.catalog() ) ) { - idGen.addParam( PersistentIdentifierGenerator.CATALOG, tabGen.catalog() ); - } - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.schema() ) ) { - idGen.addParam( PersistentIdentifierGenerator.SCHEMA, tabGen.schema() ); - } - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.table() ) ) { - idGen.addParam( org.hibernate.id.enhanced.TableGenerator.TABLE_PARAM, tabGen.table() ); - } - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.pkColumnName() ) ) { - idGen.addParam( - org.hibernate.id.enhanced.TableGenerator.SEGMENT_COLUMN_PARAM, tabGen.pkColumnName() - ); - } - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.pkColumnValue() ) ) { - idGen.addParam( - org.hibernate.id.enhanced.TableGenerator.SEGMENT_VALUE_PARAM, tabGen.pkColumnValue() - ); - } - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.valueColumnName() ) ) { - idGen.addParam( - org.hibernate.id.enhanced.TableGenerator.VALUE_COLUMN_PARAM, tabGen.valueColumnName() - ); - } - idGen.addParam( - org.hibernate.id.enhanced.TableGenerator.INCREMENT_PARAM, - String.valueOf( tabGen.allocationSize() ) - ); - // See comment on HHH-4884 wrt initialValue. Basically initialValue is really the stated value + 1 - idGen.addParam( - org.hibernate.id.enhanced.TableGenerator.INITIAL_PARAM, - String.valueOf( tabGen.initialValue() + 1 ) - ); - if (tabGen.uniqueConstraints() != null && tabGen.uniqueConstraints().length > 0) { - LOG.warn( tabGen.name() ); - } - } - else { - idGen.setStrategy( MultipleHiLoPerTableGenerator.class.getName() ); - - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.table() ) ) { - idGen.addParam( MultipleHiLoPerTableGenerator.ID_TABLE, tabGen.table() ); - } - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.catalog() ) ) { - idGen.addParam( PersistentIdentifierGenerator.CATALOG, tabGen.catalog() ); - } - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.schema() ) ) { - idGen.addParam( PersistentIdentifierGenerator.SCHEMA, tabGen.schema() ); - } - //FIXME implement uniqueconstrains - if (tabGen.uniqueConstraints() != null && tabGen.uniqueConstraints().length > 0) LOG.ignoringTableGeneratorConstraints(tabGen.name()); - - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.pkColumnName() ) ) { - idGen.addParam( MultipleHiLoPerTableGenerator.PK_COLUMN_NAME, tabGen.pkColumnName() ); - } - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.valueColumnName() ) ) { - idGen.addParam( MultipleHiLoPerTableGenerator.VALUE_COLUMN_NAME, tabGen.valueColumnName() ); - } - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.pkColumnValue() ) ) { - idGen.addParam( MultipleHiLoPerTableGenerator.PK_VALUE_NAME, tabGen.pkColumnValue() ); - } - idGen.addParam( MultipleHiLoPerTableGenerator.MAX_LO, String.valueOf( tabGen.allocationSize() - 1 ) ); - } + if ( ann instanceof TableGenerator ) { + context.getBuildingOptions().getIdGenerationTypeInterpreter().interpretTableGenerator( + (TableGenerator) ann, + definitionBuilder + ); if ( LOG.isTraceEnabled() ) { - LOG.tracev( "Add table generator with name: {0}", idGen.getName() ); + LOG.tracev( "Add table generator with name: {0}", definitionBuilder.getName() ); } } else if ( ann instanceof SequenceGenerator ) { - SequenceGenerator seqGen = ( SequenceGenerator ) ann; - idGen.setName( seqGen.name() ); - if ( useNewGeneratorMappings ) { - idGen.setStrategy( SequenceStyleGenerator.class.getName() ); - - if ( !BinderHelper.isEmptyAnnotationValue( seqGen.catalog() ) ) { - idGen.addParam( PersistentIdentifierGenerator.CATALOG, seqGen.catalog() ); - } - if ( !BinderHelper.isEmptyAnnotationValue( seqGen.schema() ) ) { - idGen.addParam( PersistentIdentifierGenerator.SCHEMA, seqGen.schema() ); - } - if ( !BinderHelper.isEmptyAnnotationValue( seqGen.sequenceName() ) ) { - idGen.addParam( SequenceStyleGenerator.SEQUENCE_PARAM, seqGen.sequenceName() ); - } - idGen.addParam( SequenceStyleGenerator.INCREMENT_PARAM, String.valueOf( seqGen.allocationSize() ) ); - idGen.addParam( SequenceStyleGenerator.INITIAL_PARAM, String.valueOf( seqGen.initialValue() ) ); - } - else { - idGen.setStrategy( "seqhilo" ); - - if ( !BinderHelper.isEmptyAnnotationValue( seqGen.sequenceName() ) ) { - idGen.addParam( org.hibernate.id.SequenceGenerator.SEQUENCE, seqGen.sequenceName() ); - } - //FIXME: work on initialValue() through SequenceGenerator.PARAMETERS - // steve : or just use o.h.id.enhanced.SequenceStyleGenerator - if ( seqGen.initialValue() != 1 ) { - LOG.unsupportedInitialValue( AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS ); - } - idGen.addParam( SequenceHiLoGenerator.MAX_LO, String.valueOf( seqGen.allocationSize() - 1 ) ); - if ( LOG.isTraceEnabled() ) { - LOG.tracev( "Add sequence generator with name: {0}", idGen.getName() ); - } + context.getBuildingOptions().getIdGenerationTypeInterpreter().interpretSequenceGenerator( + (SequenceGenerator) ann, + definitionBuilder + ); + if ( LOG.isTraceEnabled() ) { + LOG.tracev( "Add sequence generator with name: {0}", definitionBuilder.getName() ); } } else if ( ann instanceof GenericGenerator ) { GenericGenerator genGen = ( GenericGenerator ) ann; - idGen.setName( genGen.name() ); - idGen.setStrategy( genGen.strategy() ); + definitionBuilder.setName( genGen.name() ); + definitionBuilder.setStrategy( genGen.strategy() ); Parameter[] params = genGen.parameters(); for ( Parameter parameter : params ) { - idGen.addParam( parameter.name(), parameter.value() ); + definitionBuilder.addParam( parameter.name(), parameter.value() ); } if ( LOG.isTraceEnabled() ) { - LOG.tracev( "Add generic generator with name: {0}", idGen.getName() ); + LOG.tracev( "Add generic generator with name: {0}", definitionBuilder.getName() ); } } else { throw new AssertionFailure( "Unknown Generator annotation: " + ann ); } - return idGen.build(); + return definitionBuilder.build(); } /** @@ -3236,7 +3146,7 @@ public final class AnnotationBinder { final XClass javaTypeXClass) { return buildingContext.getBuildingOptions().getIdGenerationTypeInterpreter().determineGeneratorName( generatorEnum, - new IdGenerationTypeInterpreter.Context() { + new IdGeneratorStrategyInterpreter.GeneratorNameDeterminationContext() { Class javaType = null; @Override public Class getIdType() {