HHH-6488 Implementing SimpleIdentifierSource#getIdentifierGeneratorDescriptor for annotations

This commit is contained in:
Hardy Ferentschik 2011-07-27 13:40:25 +02:00
parent 9bf55b6e07
commit 3cbd2ae908
10 changed files with 299 additions and 97 deletions

View File

@ -1,11 +1,60 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.metamodel.source.annotations; package org.hibernate.metamodel.source.annotations;
import javax.persistence.GenerationType;
import org.hibernate.AssertionFailure;
import org.hibernate.id.MultipleHiLoPerTableGenerator;
/** /**
* Helper class which converts type enums from JPA annotations into the Hibernate specific form
*
* @author Hardy Ferentschik * @author Hardy Ferentschik
*/ */
public class TypeEnumConversionHelper { public class TypeEnumConversionHelper {
private TypeEnumConversionHelper() { private TypeEnumConversionHelper() {
}
public static String generationTypeToGeneratorStrategyName(GenerationType generatorEnum, boolean useNewGeneratorMappings) {
switch ( generatorEnum ) {
case IDENTITY:
return "identity";
case AUTO:
return useNewGeneratorMappings
? "enhanced-sequence"
: "native";
case TABLE:
return useNewGeneratorMappings
? "enhanced-table"
: MultipleHiLoPerTableGenerator.class.getName();
case SEQUENCE:
return useNewGeneratorMappings
? "enhanced-sequence"
: "seqhilo";
}
throw new AssertionFailure( "Unknown GeneratorType: " + generatorEnum );
} }
} }

View File

@ -34,6 +34,7 @@ import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.DotName; import org.jboss.jandex.DotName;
import org.hibernate.annotations.NotFoundAction; import org.hibernate.annotations.NotFoundAction;
import org.hibernate.metamodel.source.annotations.AnnotationBindingContext;
import org.hibernate.metamodel.source.annotations.HibernateDotNames; import org.hibernate.metamodel.source.annotations.HibernateDotNames;
import org.hibernate.metamodel.source.annotations.JandexHelper; import org.hibernate.metamodel.source.annotations.JandexHelper;
@ -50,16 +51,18 @@ public class AssociationAttribute extends BasicAttribute {
Class<?> attributeType, Class<?> attributeType,
AttributeType attributeNature, AttributeType attributeNature,
String accessType, String accessType,
Map<DotName, List<AnnotationInstance>> annotations) { Map<DotName, List<AnnotationInstance>> annotations,
return new AssociationAttribute( name, attributeType, attributeNature, accessType, annotations ); AnnotationBindingContext context) {
return new AssociationAttribute( name, attributeType, attributeNature, accessType, annotations, context );
} }
private AssociationAttribute(String name, private AssociationAttribute(String name,
Class<?> javaType, Class<?> javaType,
AttributeType associationType, AttributeType associationType,
String accessType, String accessType,
Map<DotName, List<AnnotationInstance>> annotations) { Map<DotName, List<AnnotationInstance>> annotations,
super( name, javaType, accessType, annotations ); AnnotationBindingContext context) {
super( name, javaType, accessType, annotations, context );
this.associationType = associationType; this.associationType = associationType;
this.ignoreNotFound = ignoreNotFound(); this.ignoreNotFound = ignoreNotFound();

View File

@ -28,6 +28,7 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.persistence.FetchType; import javax.persistence.FetchType;
import javax.persistence.GenerationType;
import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue; import org.jboss.jandex.AnnotationValue;
@ -35,10 +36,15 @@ import org.jboss.jandex.DotName;
import org.hibernate.AnnotationException; import org.hibernate.AnnotationException;
import org.hibernate.annotations.GenerationTime; import org.hibernate.annotations.GenerationTime;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.PropertyGeneration; import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.binding.IdGenerator;
import org.hibernate.metamodel.source.MappingException;
import org.hibernate.metamodel.source.annotations.AnnotationBindingContext;
import org.hibernate.metamodel.source.annotations.HibernateDotNames; import org.hibernate.metamodel.source.annotations.HibernateDotNames;
import org.hibernate.metamodel.source.annotations.JPADotNames; import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.metamodel.source.annotations.JandexHelper; import org.hibernate.metamodel.source.annotations.JandexHelper;
import org.hibernate.metamodel.source.annotations.TypeEnumConversionHelper;
/** /**
* Represent a mapped attribute (explicitly or implicitly mapped). * Represent a mapped attribute (explicitly or implicitly mapped).
@ -51,6 +57,12 @@ public class BasicAttribute extends MappedAttribute {
*/ */
private final boolean isId; private final boolean isId;
/**
* The id generator in case this basic attribute represents an simple id. Will be {@code null} in case there
* is no explicit id generator or the containing entity does not have a simple id
*/
private final IdGenerator idGenerator;
/** /**
* Is this a versioned property (annotated w/ {@code @Version}. * Is this a versioned property (annotated w/ {@code @Version}.
*/ */
@ -88,12 +100,20 @@ public class BasicAttribute extends MappedAttribute {
private final String customReadFragment; private final String customReadFragment;
private final String checkCondition; private final String checkCondition;
public static BasicAttribute createSimpleAttribute(String name, Class<?> attributeType, Map<DotName, List<AnnotationInstance>> annotations, String accessType) { public static BasicAttribute createSimpleAttribute(String name,
return new BasicAttribute( name, attributeType, accessType, annotations ); Class<?> attributeType,
Map<DotName, List<AnnotationInstance>> annotations,
String accessType,
AnnotationBindingContext context) {
return new BasicAttribute( name, attributeType, accessType, annotations, context );
} }
BasicAttribute(String name, Class<?> attributeType, String accessType, Map<DotName, List<AnnotationInstance>> annotations) { BasicAttribute(String name,
super( name, attributeType, accessType, annotations ); Class<?> attributeType,
String accessType,
Map<DotName, List<AnnotationInstance>> annotations,
AnnotationBindingContext context) {
super( name, attributeType, accessType, annotations, context );
AnnotationInstance idAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ID ); AnnotationInstance idAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ID );
AnnotationInstance embeddedIdAnnotation = JandexHelper.getSingleAnnotation( AnnotationInstance embeddedIdAnnotation = JandexHelper.getSingleAnnotation(
@ -112,6 +132,10 @@ public class BasicAttribute extends MappedAttribute {
// an id must be unique and cannot be nullable // an id must be unique and cannot be nullable
columnValues.setUnique( true ); columnValues.setUnique( true );
columnValues.setNullable( false ); columnValues.setNullable( false );
idGenerator = checkGeneratedValueAnnotation();
}
else {
idGenerator = null;
} }
this.isOptimisticLockable = checkOptimisticLockAnnotation(); this.isOptimisticLockable = checkOptimisticLockAnnotation();
@ -175,6 +199,10 @@ public class BasicAttribute extends MappedAttribute {
return checkCondition; return checkCondition;
} }
public IdGenerator getIdGenerator() {
return idGenerator;
}
@Override @Override
public String toString() { public String toString() {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
@ -290,6 +318,36 @@ public class BasicAttribute extends MappedAttribute {
} }
return checkCondition; return checkCondition;
} }
private IdGenerator checkGeneratedValueAnnotation() {
IdGenerator generator = null;
AnnotationInstance generatedValueAnnotation = JandexHelper.getSingleAnnotation(
annotations(),
JPADotNames.GENERATED_VALUE
);
if ( generatedValueAnnotation != null ) {
String name = JandexHelper.getValue( generatedValueAnnotation, "generator", String.class );
if ( StringHelper.isNotEmpty( name ) ) {
generator = getContext().getMetadataImplementor().getIdGenerator( name );
if ( generator == null ) {
throw new MappingException( String.format( "Unable to find named generator %s", name ), null );
}
}
else {
GenerationType genType = JandexHelper.getEnumValue(
generatedValueAnnotation,
"strategy",
GenerationType.class
);
String strategy = TypeEnumConversionHelper.generationTypeToGeneratorStrategyName(
genType,
getContext().getMetadataImplementor().getOptions().useNewIdentifierGenerators()
);
generator = new IdGenerator( null, strategy, null );
}
}
return generator;
}
} }

View File

@ -31,6 +31,7 @@ import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue; import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.DotName; import org.jboss.jandex.DotName;
import org.hibernate.metamodel.source.annotations.AnnotationBindingContext;
import org.hibernate.metamodel.source.annotations.HibernateDotNames; import org.hibernate.metamodel.source.annotations.HibernateDotNames;
import org.hibernate.metamodel.source.annotations.JandexHelper; import org.hibernate.metamodel.source.annotations.JandexHelper;
@ -71,13 +72,19 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
*/ */
private final Map<String, String> explicitHibernateTypeParameters; private final Map<String, String> explicitHibernateTypeParameters;
MappedAttribute(String name, Class<?> attributeType, String accessType, Map<DotName, List<AnnotationInstance>> annotations) { private final AnnotationBindingContext context;
MappedAttribute(String name, Class<?> attributeType, String accessType, Map<DotName, List<AnnotationInstance>> annotations, AnnotationBindingContext context) {
this.context = context;
this.annotations = annotations; this.annotations = annotations;
this.name = name; this.name = name;
this.attributeType = attributeType; this.attributeType = attributeType;
this.accessType = accessType; this.accessType = accessType;
final AnnotationInstance typeAnnotation = JandexHelper.getSingleAnnotation(annotations(), HibernateDotNames.TYPE ); final AnnotationInstance typeAnnotation = JandexHelper.getSingleAnnotation(
annotations(),
HibernateDotNames.TYPE
);
if ( typeAnnotation != null ) { if ( typeAnnotation != null ) {
this.explicitHibernateTypeName = typeAnnotation.value( "type" ).asString(); this.explicitHibernateTypeName = typeAnnotation.value( "type" ).asString();
this.explicitHibernateTypeParameters = extractTypeParameters( typeAnnotation ); this.explicitHibernateTypeParameters = extractTypeParameters( typeAnnotation );
@ -123,6 +130,10 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
return explicitHibernateTypeParameters; return explicitHibernateTypeParameters;
} }
public AnnotationBindingContext getContext() {
return context;
}
Map<DotName, List<AnnotationInstance>> annotations() { Map<DotName, List<AnnotationInstance>> annotations() {
return annotations; return annotations;
} }

View File

@ -23,6 +23,7 @@
*/ */
package org.hibernate.metamodel.source.annotations.attribute; package org.hibernate.metamodel.source.annotations.attribute;
import org.hibernate.AssertionFailure;
import org.hibernate.metamodel.binding.IdGenerator; import org.hibernate.metamodel.binding.IdGenerator;
import org.hibernate.metamodel.source.binder.SimpleIdentifierSource; import org.hibernate.metamodel.source.binder.SimpleIdentifierSource;
import org.hibernate.metamodel.source.binder.SingularAttributeSource; import org.hibernate.metamodel.source.binder.SingularAttributeSource;
@ -34,6 +35,14 @@ public class SimpleIdentifierSourceImpl implements SimpleIdentifierSource {
private final BasicAttribute attribute; private final BasicAttribute attribute;
public SimpleIdentifierSourceImpl(BasicAttribute attribute) { public SimpleIdentifierSourceImpl(BasicAttribute attribute) {
if ( !attribute.isId() ) {
throw new AssertionFailure(
String.format(
"A non id attribute was passed to SimpleIdentifierSourceImpl: %s",
attribute.toString()
)
);
}
this.attribute = attribute; this.attribute = attribute;
} }
@ -49,7 +58,7 @@ public class SimpleIdentifierSourceImpl implements SimpleIdentifierSource {
@Override @Override
public IdGenerator getIdentifierGeneratorDescriptor() { public IdGenerator getIdentifierGeneratorDescriptor() {
return null; //To change body of implemented methods use File | Settings | File Templates. return attribute.getIdGenerator();
} }
} }

View File

@ -60,8 +60,8 @@ import org.hibernate.metamodel.source.annotations.ReflectionHelper;
import org.hibernate.metamodel.source.annotations.attribute.AssociationAttribute; import org.hibernate.metamodel.source.annotations.attribute.AssociationAttribute;
import org.hibernate.metamodel.source.annotations.attribute.AttributeOverride; import org.hibernate.metamodel.source.annotations.attribute.AttributeOverride;
import org.hibernate.metamodel.source.annotations.attribute.AttributeType; import org.hibernate.metamodel.source.annotations.attribute.AttributeType;
import org.hibernate.metamodel.source.annotations.attribute.MappedAttribute;
import org.hibernate.metamodel.source.annotations.attribute.BasicAttribute; import org.hibernate.metamodel.source.annotations.attribute.BasicAttribute;
import org.hibernate.metamodel.source.annotations.attribute.MappedAttribute;
/** /**
* Base class for a configured entity, mapped super class or embeddable * Base class for a configured entity, mapped super class or embeddable
@ -246,7 +246,7 @@ public class ConfiguredClass {
AnnotationInstance accessAnnotation = JandexHelper.getSingleAnnotation( classInfo, JPADotNames.ACCESS ); AnnotationInstance accessAnnotation = JandexHelper.getSingleAnnotation( classInfo, JPADotNames.ACCESS );
if ( accessAnnotation != null && accessAnnotation.target().getClass().equals( ClassInfo.class ) ) { if ( accessAnnotation != null && accessAnnotation.target().getClass().equals( ClassInfo.class ) ) {
accessType = JandexHelper.getValueAsEnum( accessAnnotation, "value", AccessType.class ); accessType = JandexHelper.getEnumValue( accessAnnotation, "value", AccessType.class );
} }
return accessType; return accessType;
@ -334,7 +334,7 @@ public class ConfiguredClass {
continue; continue;
} }
AccessType accessType = JandexHelper.getValueAsEnum( accessAnnotation, "value", AccessType.class ); AccessType accessType = JandexHelper.getEnumValue( accessAnnotation, "value", AccessType.class );
if ( !isExplicitAttributeAccessAnnotationPlacedCorrectly( annotationTarget, accessType ) ) { if ( !isExplicitAttributeAccessAnnotationPlacedCorrectly( annotationTarget, accessType ) ) {
continue; continue;
@ -446,7 +446,7 @@ public class ConfiguredClass {
switch ( attributeNature ) { switch ( attributeNature ) {
case BASIC: { case BASIC: {
BasicAttribute attribute = BasicAttribute.createSimpleAttribute( BasicAttribute attribute = BasicAttribute.createSimpleAttribute(
attributeName, attributeType, annotations, accessTypeString attributeName, attributeType, annotations, accessTypeString, getContext()
); );
if ( attribute.isId() ) { if ( attribute.isId() ) {
idAttributeMap.put( attributeName, attribute ); idAttributeMap.put( attributeName, attribute );
@ -469,7 +469,7 @@ public class ConfiguredClass {
// TODO handle the different association types // TODO handle the different association types
default: { default: {
AssociationAttribute attribute = AssociationAttribute.createAssociationAttribute( AssociationAttribute attribute = AssociationAttribute.createAssociationAttribute(
attributeName, attributeType, attributeNature, accessTypeString, annotations attributeName, attributeType, attributeNature, accessTypeString, annotations, getContext()
); );
associationAttributeMap.put( attributeName, attribute ); associationAttributeMap.put( attributeName, attribute );
} }

View File

@ -32,7 +32,6 @@ import javax.persistence.SequenceGenerator;
import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationInstance;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.hibernate.AssertionFailure;
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.GenericGenerators; import org.hibernate.annotations.GenericGenerators;
import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.AvailableSettings;
@ -50,6 +49,7 @@ import org.hibernate.metamodel.source.annotations.AnnotationBindingContext;
import org.hibernate.metamodel.source.annotations.HibernateDotNames; import org.hibernate.metamodel.source.annotations.HibernateDotNames;
import org.hibernate.metamodel.source.annotations.JPADotNames; import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.metamodel.source.annotations.JandexHelper; import org.hibernate.metamodel.source.annotations.JandexHelper;
import org.hibernate.metamodel.source.annotations.TypeEnumConversionHelper;
/** /**
* Binds {@link SequenceGenerator}, {@link javax.persistence.TableGenerator}, {@link GenericGenerator}, and * Binds {@link SequenceGenerator}, {@link javax.persistence.TableGenerator}, {@link GenericGenerator}, and
@ -138,19 +138,21 @@ public class IdGeneratorBinder {
private static void bindSequenceGenerator(MetadataImplementor metadata, AnnotationInstance generator) { private static void bindSequenceGenerator(MetadataImplementor metadata, AnnotationInstance generator) {
String name = JandexHelper.getValue( generator, "name", String.class ); String name = JandexHelper.getValue( generator, "name", String.class );
String strategy; Map<String, String> parameterMap = new HashMap<String, String>();
Map<String, String> prms = new HashMap<String, String>(); addStringParameter( generator, "sequenceName", parameterMap, SequenceStyleGenerator.SEQUENCE_PARAM );
addStringParameter( generator, "sequenceName", prms, SequenceStyleGenerator.SEQUENCE_PARAM );
boolean useNewIdentifierGenerators = metadata.getOptions().useNewIdentifierGenerators(); boolean useNewIdentifierGenerators = metadata.getOptions().useNewIdentifierGenerators();
strategy = generatorType( GenerationType.SEQUENCE, useNewIdentifierGenerators ); String strategy = TypeEnumConversionHelper.generationTypeToGeneratorStrategyName(
GenerationType.SEQUENCE,
useNewIdentifierGenerators
);
if ( useNewIdentifierGenerators ) { if ( useNewIdentifierGenerators ) {
addStringParameter( generator, "catalog", prms, PersistentIdentifierGenerator.CATALOG ); addStringParameter( generator, "catalog", parameterMap, PersistentIdentifierGenerator.CATALOG );
addStringParameter( generator, "schema", prms, PersistentIdentifierGenerator.SCHEMA ); addStringParameter( generator, "schema", parameterMap, PersistentIdentifierGenerator.SCHEMA );
prms.put( parameterMap.put(
SequenceStyleGenerator.INCREMENT_PARAM, SequenceStyleGenerator.INCREMENT_PARAM,
String.valueOf( JandexHelper.getValue( generator, "allocationSize", Integer.class ) ) String.valueOf( JandexHelper.getValue( generator, "allocationSize", Integer.class ) )
); );
prms.put( parameterMap.put(
SequenceStyleGenerator.INITIAL_PARAM, SequenceStyleGenerator.INITIAL_PARAM,
String.valueOf( JandexHelper.getValue( generator, "initialValue", Integer.class ) ) String.valueOf( JandexHelper.getValue( generator, "initialValue", Integer.class ) )
); );
@ -159,44 +161,46 @@ public class IdGeneratorBinder {
if ( JandexHelper.getValue( generator, "initialValue", Integer.class ) != 1 ) { if ( JandexHelper.getValue( generator, "initialValue", Integer.class ) != 1 ) {
LOG.unsupportedInitialValue( AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS ); LOG.unsupportedInitialValue( AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS );
} }
prms.put( parameterMap.put(
SequenceHiLoGenerator.MAX_LO, SequenceHiLoGenerator.MAX_LO,
String.valueOf( JandexHelper.getValue( generator, "allocationSize", Integer.class ) - 1 ) String.valueOf( JandexHelper.getValue( generator, "allocationSize", Integer.class ) - 1 )
); );
} }
metadata.addIdGenerator( new IdGenerator( name, strategy, prms ) ); metadata.addIdGenerator( new IdGenerator( name, strategy, parameterMap ) );
LOG.tracef( "Add sequence generator with name: %s", name ); LOG.tracef( "Add sequence generator with name: %s", name );
} }
private static void bindTableGenerator(MetadataImplementor metadata, AnnotationInstance generator) { private static void bindTableGenerator(MetadataImplementor metadata, AnnotationInstance generator) {
String name = JandexHelper.getValue( generator, "name", String.class ); String name = JandexHelper.getValue( generator, "name", String.class );
String strategy; Map<String, String> parameterMap = new HashMap<String, String>();
Map<String, String> prms = new HashMap<String, String>(); addStringParameter( generator, "catalog", parameterMap, PersistentIdentifierGenerator.CATALOG );
addStringParameter( generator, "catalog", prms, PersistentIdentifierGenerator.CATALOG ); addStringParameter( generator, "schema", parameterMap, PersistentIdentifierGenerator.SCHEMA );
addStringParameter( generator, "schema", prms, PersistentIdentifierGenerator.SCHEMA );
boolean useNewIdentifierGenerators = metadata.getOptions().useNewIdentifierGenerators(); boolean useNewIdentifierGenerators = metadata.getOptions().useNewIdentifierGenerators();
strategy = generatorType( GenerationType.TABLE, useNewIdentifierGenerators ); String strategy = TypeEnumConversionHelper.generationTypeToGeneratorStrategyName(
GenerationType.TABLE,
useNewIdentifierGenerators
);
if ( useNewIdentifierGenerators ) { if ( useNewIdentifierGenerators ) {
prms.put( TableGenerator.CONFIG_PREFER_SEGMENT_PER_ENTITY, "true" ); parameterMap.put( TableGenerator.CONFIG_PREFER_SEGMENT_PER_ENTITY, "true" );
addStringParameter( generator, "table", prms, TableGenerator.TABLE_PARAM ); addStringParameter( generator, "table", parameterMap, TableGenerator.TABLE_PARAM );
addStringParameter( generator, "pkColumnName", prms, TableGenerator.SEGMENT_COLUMN_PARAM ); addStringParameter( generator, "pkColumnName", parameterMap, TableGenerator.SEGMENT_COLUMN_PARAM );
addStringParameter( generator, "pkColumnValue", prms, TableGenerator.SEGMENT_VALUE_PARAM ); addStringParameter( generator, "pkColumnValue", parameterMap, TableGenerator.SEGMENT_VALUE_PARAM );
addStringParameter( generator, "valueColumnName", prms, TableGenerator.VALUE_COLUMN_PARAM ); addStringParameter( generator, "valueColumnName", parameterMap, TableGenerator.VALUE_COLUMN_PARAM );
prms.put( parameterMap.put(
TableGenerator.INCREMENT_PARAM, TableGenerator.INCREMENT_PARAM,
String.valueOf( JandexHelper.getValue( generator, "allocationSize", String.class ) ) String.valueOf( JandexHelper.getValue( generator, "allocationSize", String.class ) )
); );
prms.put( parameterMap.put(
TableGenerator.INITIAL_PARAM, TableGenerator.INITIAL_PARAM,
String.valueOf( JandexHelper.getValue( generator, "initialValue", String.class ) + 1 ) String.valueOf( JandexHelper.getValue( generator, "initialValue", String.class ) + 1 )
); );
} }
else { else {
addStringParameter( generator, "table", prms, MultipleHiLoPerTableGenerator.ID_TABLE ); addStringParameter( generator, "table", parameterMap, MultipleHiLoPerTableGenerator.ID_TABLE );
addStringParameter( generator, "pkColumnName", prms, MultipleHiLoPerTableGenerator.PK_COLUMN_NAME ); addStringParameter( generator, "pkColumnName", parameterMap, MultipleHiLoPerTableGenerator.PK_COLUMN_NAME );
addStringParameter( generator, "pkColumnValue", prms, MultipleHiLoPerTableGenerator.PK_VALUE_NAME ); addStringParameter( generator, "pkColumnValue", parameterMap, MultipleHiLoPerTableGenerator.PK_VALUE_NAME );
addStringParameter( generator, "valueColumnName", prms, MultipleHiLoPerTableGenerator.VALUE_COLUMN_NAME ); addStringParameter( generator, "valueColumnName", parameterMap, MultipleHiLoPerTableGenerator.VALUE_COLUMN_NAME );
prms.put( parameterMap.put(
TableHiLoGenerator.MAX_LO, TableHiLoGenerator.MAX_LO,
String.valueOf( JandexHelper.getValue( generator, "allocationSize", Integer.class ) - 1 ) String.valueOf( JandexHelper.getValue( generator, "allocationSize", Integer.class ) - 1 )
); );
@ -204,27 +208,7 @@ public class IdGeneratorBinder {
if ( JandexHelper.getValue( generator, "uniqueConstraints", AnnotationInstance[].class ).length > 0 ) { if ( JandexHelper.getValue( generator, "uniqueConstraints", AnnotationInstance[].class ).length > 0 ) {
LOG.ignoringTableGeneratorConstraints( name ); LOG.ignoringTableGeneratorConstraints( name );
} }
metadata.addIdGenerator( new IdGenerator( name, strategy, prms ) ); metadata.addIdGenerator( new IdGenerator( name, strategy, parameterMap ) );
LOG.tracef( "Add table generator with name: %s", name ); LOG.tracef( "Add table generator with name: %s", name );
} }
public static String generatorType(GenerationType generatorEnum, boolean useNewGeneratorMappings) {
switch ( generatorEnum ) {
case IDENTITY:
return "identity";
case AUTO:
return useNewGeneratorMappings
? "enhanced-sequence"
: "native";
case TABLE:
return useNewGeneratorMappings
? "enhanced-table"
: MultipleHiLoPerTableGenerator.class.getName();
case SEQUENCE:
return useNewGeneratorMappings
? "enhanced-sequence"
: "seqhilo";
}
throw new AssertionFailure( "Unknown GeneratorType: " + generatorEnum );
}
} }

View File

@ -59,7 +59,7 @@ class AccessHelper implements JPADotNames {
return null; return null;
} }
else { else {
return JandexHelper.getValueAsEnum( annotationInstance, "value", XMLAccessType.class ); return JandexHelper.getEnumValue( annotationInstance, "value", XMLAccessType.class );
} }
} }
@ -149,7 +149,7 @@ class AccessHelper implements JPADotNames {
if ( MockHelper.isNotEmpty( accessAnnotationInstances ) ) { if ( MockHelper.isNotEmpty( accessAnnotationInstances ) ) {
for ( AnnotationInstance annotationInstance : accessAnnotationInstances ) { for ( AnnotationInstance annotationInstance : accessAnnotationInstances ) {
if ( annotationInstance.target() != null && annotationInstance.target() instanceof ClassInfo ) { if ( annotationInstance.target() != null && annotationInstance.target() instanceof ClassInfo ) {
return JandexHelper.getValueAsEnum( return JandexHelper.getEnumValue(
annotationInstance, annotationInstance,
"value", "value",
XMLAccessType.class XMLAccessType.class
@ -179,7 +179,7 @@ class AccessHelper implements JPADotNames {
continue; continue;
} }
if ( JandexHelper.getPropertyName( indexedPropertyTarget ).equals( attributeName ) ) { if ( JandexHelper.getPropertyName( indexedPropertyTarget ).equals( attributeName ) ) {
XMLAccessType accessType = JandexHelper.getValueAsEnum( XMLAccessType accessType = JandexHelper.getEnumValue(
annotationInstance, annotationInstance,
"value", "value",
XMLAccessType.class XMLAccessType.class

View File

@ -531,7 +531,7 @@ public class Binder {
private Class<?> determineJavaType(final Attribute attribute) { private Class<?> determineJavaType(final Attribute attribute) {
try { try {
final Class ownerClass = attribute.getAttributeContainer().getClassReference(); final Class<?> ownerClass = attribute.getAttributeContainer().getClassReference();
AttributeJavaTypeDeterminerDelegate delegate = new AttributeJavaTypeDeterminerDelegate( attribute.getName() ); AttributeJavaTypeDeterminerDelegate delegate = new AttributeJavaTypeDeterminerDelegate( attribute.getName() );
BeanInfoHelper.visitBeanInfo( ownerClass, delegate ); BeanInfoHelper.visitBeanInfo( ownerClass, delegate );
return delegate.javaType; return delegate.javaType;

View File

@ -1,20 +1,25 @@
package org.hibernate.metamodel.source.annotations.entity; package org.hibernate.metamodel.source.annotations.entity;
import java.util.Iterator;
import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.SecondaryTable;
import org.junit.Test; import org.junit.Test;
import org.hibernate.AssertionFailure; import org.hibernate.annotations.GenericGenerator;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.IdentityGenerator;
import org.hibernate.id.MultipleHiLoPerTableGenerator;
import org.hibernate.id.SequenceHiLoGenerator;
import org.hibernate.id.UUIDHexGenerator;
import org.hibernate.metamodel.MetadataSources;
import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.relational.SimpleValue; import org.hibernate.metamodel.source.MappingException;
import org.hibernate.metamodel.relational.Table; import org.hibernate.service.ServiceRegistryBuilder;
import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue; import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail; import static junit.framework.Assert.fail;
@ -23,41 +28,124 @@ import static junit.framework.Assert.fail;
*/ */
public class IdentifierGeneratorTest extends BaseAnnotationBindingTestCase { public class IdentifierGeneratorTest extends BaseAnnotationBindingTestCase {
@Entity @Entity
@SecondaryTable(name = "SECOND_TABLE") class NoGenerationEntity {
class EntityWithSecondaryTable {
@Id @Id
private long id; private long id;
@Column(table = "SECOND_TABLE")
private String name;
} }
@Test @Test
@Resources(annotatedClasses = EntityWithSecondaryTable.class) @Resources(annotatedClasses = NoGenerationEntity.class)
public void testSecondaryTableExists() { public void testNoIdGeneration() {
EntityBinding binding = getEntityBinding( EntityWithSecondaryTable.class ); EntityBinding binding = getEntityBinding( NoGenerationEntity.class );
Table table = (Table) binding.getTable( "SECOND_TABLE" ); IdentifierGenerator generator = binding.getHierarchyDetails().getEntityIdentifier().getIdentifierGenerator();
assertEquals( "The secondary table should exist", "SECOND_TABLE", table.getTableName().getName() ); assertNull( generator );
}
Iterator<SimpleValue> valueIterator = table.values().iterator(); @Entity
assertTrue( valueIterator.hasNext() ); class AutoEntity {
org.hibernate.metamodel.relational.Column column = (org.hibernate.metamodel.relational.Column) valueIterator.next(); @Id
assertEquals( "Wrong column name", "name", column.getColumnName().getName() ); @GeneratedValue
assertFalse( valueIterator.hasNext() ); private long id;
public long getId() {
return id;
}
} }
@Test @Test
@Resources(annotatedClasses = EntityWithSecondaryTable.class) @Resources(annotatedClasses = AutoEntity.class)
public void testRetrievingUnknownTable() { public void testAutoGenerationType() {
EntityBinding binding = getEntityBinding( EntityWithSecondaryTable.class ); EntityBinding binding = getEntityBinding( AutoEntity.class );
IdentifierGenerator generator = binding.getHierarchyDetails().getEntityIdentifier().getIdentifierGenerator();
assertEquals( "Wrong generator", IdentityGenerator.class, generator.getClass() );
}
@Entity
class TableEntity {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private long id;
public long getId() {
return id;
}
}
@Test
@Resources(annotatedClasses = TableEntity.class)
public void testTableGenerationType() {
EntityBinding binding = getEntityBinding( TableEntity.class );
IdentifierGenerator generator = binding.getHierarchyDetails().getEntityIdentifier().getIdentifierGenerator();
assertEquals( "Wrong generator", MultipleHiLoPerTableGenerator.class, generator.getClass() );
}
@Entity
class SequenceEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private long id;
public long getId() {
return id;
}
}
@Test
@Resources(annotatedClasses = SequenceEntity.class)
public void testSequenceGenerationType() {
EntityBinding binding = getEntityBinding( SequenceEntity.class );
IdentifierGenerator generator = binding.getHierarchyDetails().getEntityIdentifier().getIdentifierGenerator();
assertEquals( "Wrong generator", SequenceHiLoGenerator.class, generator.getClass() );
}
@Entity
class NamedGeneratorEntity {
@Id
@GeneratedValue(generator = "my-generator")
private long id;
public long getId() {
return id;
}
}
@Test
public void testUndefinedGenerator() {
try { try {
binding.getTable( "FOO" ); sources = new MetadataSources( new ServiceRegistryBuilder().buildServiceRegistry() );
sources.addAnnotatedClass( NamedGeneratorEntity.class );
sources.buildMetadata();
fail(); fail();
} }
catch ( AssertionFailure e ) { catch ( MappingException e ) {
assertTrue( e.getMessage().startsWith( "Unable to find table" ) ); assertTrue( e.getMessage().startsWith( "Unable to find named generator" ) );
} }
} }
@Entity
@GenericGenerator(name = "my-generator", strategy = "uuid")
class NamedGeneratorEntity2 {
@Id
@GeneratedValue(generator = "my-generator")
private long id;
public long getId() {
return id;
}
}
@Test
@Resources(annotatedClasses = NamedGeneratorEntity2.class)
public void testNamedGenerator() {
EntityBinding binding = getEntityBinding( NamedGeneratorEntity2.class );
IdentifierGenerator generator = binding.getHierarchyDetails().getEntityIdentifier().getIdentifierGenerator();
assertEquals( "Wrong generator", UUIDHexGenerator.class, generator.getClass() );
}
} }