diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/Metadata.java b/hibernate-core/src/main/java/org/hibernate/metamodel/Metadata.java index d972516a22..38e2bd50f6 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/Metadata.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/Metadata.java @@ -24,10 +24,8 @@ package org.hibernate.metamodel; import java.util.Map; -import javax.persistence.SharedCacheMode; -import org.jboss.jandex.IndexView; -import org.xml.sax.EntityResolver; +import javax.persistence.SharedCacheMode; import org.hibernate.MultiTenancyStrategy; import org.hibernate.SessionFactory; @@ -43,6 +41,8 @@ import org.hibernate.metamodel.spi.binding.FetchProfile; import org.hibernate.metamodel.spi.binding.IdGenerator; import org.hibernate.metamodel.spi.binding.PluralAttributeBinding; import org.hibernate.metamodel.spi.binding.TypeDefinition; +import org.jboss.jandex.IndexView; +import org.xml.sax.EntityResolver; /** * @author Steve Ebersole @@ -102,6 +102,8 @@ public interface Metadata { public Iterable getCollectionBindings(); + public boolean hasTypeDefinition(String name); + public TypeDefinition getTypeDefinition(String name); public Iterable getTypeDefinitions(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/Binder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/Binder.java index 2db464289d..5a59216351 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/Binder.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/Binder.java @@ -366,10 +366,9 @@ public class Binder { createMetaAttributeContext( attributeBindingContainer, attributeSource ), attributeSource.getGeneration() ); final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding.getHibernateTypeDescriptor(); - bindHibernateTypeDescriptor( - attributeBinding.getHibernateTypeDescriptor(), - attributeSource.getTypeInformation(), - createSingularAttributeJavaType( attributeBinding.getAttribute() ) ); + typeHelper.bindSingularAttributeTypeInformation( attributeSource, + attributeBinding ); + // TODO: Move heuristic type into typeHelper? Type resolvedType = heuristicType( hibernateTypeDescriptor ); bindHibernateResolvedType( attributeBinding.getHibernateTypeDescriptor(), resolvedType ); typeHelper.bindJdbcDataType( resolvedType, relationalValueBindings ); @@ -845,6 +844,9 @@ public class Binder { } } + // TODO: The following 3 methods should eventually be replaced w/ + // typeHelper use. + private void bindHibernateTypeDescriptor( final HibernateTypeDescriptor hibernateTypeDescriptor, final ExplicitHibernateTypeSource explicitTypeSource, diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/HibernateTypeHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/HibernateTypeHelper.java index b8405cf4d3..965ffd5ae0 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/HibernateTypeHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/HibernateTypeHelper.java @@ -31,16 +31,14 @@ import java.util.List; import java.util.Map; import java.util.Properties; -import org.jboss.logging.Logger; - import org.hibernate.AssertionFailure; import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.beans.BeanInfoHelper; import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.metamodel.spi.MetadataImplementor; -import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding; import org.hibernate.metamodel.spi.binding.AttributeBinding; import org.hibernate.metamodel.spi.binding.BasicAttributeBinding; +import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding; import org.hibernate.metamodel.spi.binding.HibernateTypeDescriptor; import org.hibernate.metamodel.spi.binding.PluralAttributeBinding; import org.hibernate.metamodel.spi.binding.RelationalValueBinding; @@ -58,6 +56,7 @@ import org.hibernate.metamodel.spi.source.SingularAttributeSource; import org.hibernate.type.ComponentType; import org.hibernate.type.EntityType; import org.hibernate.type.Type; +import org.jboss.logging.Logger; /** * Delegate for handling:
    @@ -80,12 +79,12 @@ import org.hibernate.type.Type; *

    * Currently the following methods are also required to be non-private because of handling discriminators which * are currently not modeled using attributes:

      - *
    • {@link #determineHibernateTypeFromDescriptor}
    • *
    • {@link #bindJdbcDataType(org.hibernate.type.Type, org.hibernate.metamodel.spi.relational.Value)}
    • *
    * * @author Steve Ebersole * @author Gail Badner + * @author Brett Meyer */ public class HibernateTypeHelper { private static final Logger log = Logger.getLogger( HibernateTypeHelper.class ); @@ -106,19 +105,25 @@ public class HibernateTypeHelper { public void bindSingularAttributeTypeInformation( SingularAttributeSource attributeSource, SingularAttributeBinding attributeBinding) { - final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding.getHibernateTypeDescriptor(); + final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding + .getHibernateTypeDescriptor(); - final Class attributeJavaType = determineJavaType( attributeBinding.getAttribute() ); + final Class attributeJavaType = determineJavaType( + attributeBinding.getAttribute() ); if ( attributeJavaType != null ) { - attributeBinding.getAttribute().resolveType( makeJavaType( attributeJavaType.getName() ) ); + attributeBinding.getAttribute().resolveType( makeJavaType( + attributeJavaType.getName() ) ); if ( hibernateTypeDescriptor.getJavaTypeName() == null ) { - hibernateTypeDescriptor.setJavaTypeName( attributeJavaType.getName() ); + hibernateTypeDescriptor.setJavaTypeName( + attributeJavaType.getName() ); } } - bindHibernateTypeInformation( attributeSource.getTypeInformation(), hibernateTypeDescriptor ); + bindHibernateTypeInformation( attributeSource.getTypeInformation(), + hibernateTypeDescriptor ); - processSingularAttributeTypeInformation( attributeSource, attributeBinding ); + processSingularAttributeTypeInformation( attributeSource, + attributeBinding ); } public ReflectedCollectionJavaTypes getReflectedCollectionJavaTypes( @@ -168,21 +173,31 @@ public class HibernateTypeHelper { * @param hibernateTypeDescriptor The binding model hibernate type information */ private void bindHibernateTypeInformation( - ExplicitHibernateTypeSource typeSource, - HibernateTypeDescriptor hibernateTypeDescriptor) { + final ExplicitHibernateTypeSource typeSource, + final HibernateTypeDescriptor hibernateTypeDescriptor) { + final String explicitTypeName = typeSource.getName(); + if ( explicitTypeName != null ) { - final TypeDefinition typeDefinition = metadata.getTypeDefinition( explicitTypeName ); + final TypeDefinition typeDefinition = metadata.getTypeDefinition( + explicitTypeName ); if ( typeDefinition != null ) { - hibernateTypeDescriptor.setExplicitTypeName( typeDefinition.getTypeImplementorClass().getName() ); - hibernateTypeDescriptor.getTypeParameters().putAll( typeDefinition.getParameters() ); + hibernateTypeDescriptor.setExplicitTypeName( + typeDefinition.getTypeImplementorClass().getName() ); + // Don't use set() -- typeDef#parameters is unmodifiable + hibernateTypeDescriptor.getTypeParameters().putAll( + typeDefinition.getParameters() ); } else { hibernateTypeDescriptor.setExplicitTypeName( explicitTypeName ); } + + // TODO: Should type parameters be used for @TypeDefs? final Map parameters = typeSource.getParameters(); if ( parameters != null ) { - hibernateTypeDescriptor.getTypeParameters().putAll( parameters ); + // Don't use set() -- typeDef#parameters is unmodifiable + hibernateTypeDescriptor.getTypeParameters().putAll( + parameters ); } } } @@ -214,7 +229,7 @@ public class HibernateTypeHelper { } } - public Type determineHibernateTypeFromDescriptor(HibernateTypeDescriptor hibernateTypeDescriptor) { + private Type determineHibernateTypeFromDescriptor(HibernateTypeDescriptor hibernateTypeDescriptor) { if ( hibernateTypeDescriptor.getResolvedTypeMapping() != null ) { return hibernateTypeDescriptor.getResolvedTypeMapping(); } @@ -344,6 +359,9 @@ public class HibernateTypeHelper { if ( hibernateTypeDescriptor.getJavaTypeName() == null ) { hibernateTypeDescriptor.setJavaTypeName( resolvedHibernateType.getReturnedClass().getName() ); } + + hibernateTypeDescriptor.setToOne( resolvedHibernateType.isEntityType() ); + bindJdbcDataType( resolvedHibernateType, relationalValueBindings ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataImpl.java index 6c14b14468..f711392ee5 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataImpl.java @@ -29,13 +29,11 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.jboss.jandex.IndexView; -import org.jboss.logging.Logger; - import org.hibernate.AssertionFailure; import org.hibernate.DuplicateMappingException; import org.hibernate.MappingException; import org.hibernate.SessionFactory; +import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cfg.NamingStrategy; import org.hibernate.cfg.ObjectNameNormalizer; @@ -83,8 +81,9 @@ import org.hibernate.metamodel.spi.source.MappingDefaults; import org.hibernate.metamodel.spi.source.MetaAttributeContext; import org.hibernate.metamodel.spi.source.TypeDescriptorSource; import org.hibernate.service.ServiceRegistry; -import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.type.TypeResolver; +import org.jboss.jandex.IndexView; +import org.jboss.logging.Logger; /** * Container for configuration data collected during binding the metamodel. @@ -227,16 +226,29 @@ public class MetadataImpl implements MetadataImplementor, Serializable { } @Override - public void addTypeDefinition(TypeDefinition typeDefinition) { + public void addTypeDefinition( TypeDefinition typeDefinition ) { if ( typeDefinition == null ) { throw new IllegalArgumentException( "Type definition is null" ); } else if ( typeDefinition.getName() == null ) { throw new IllegalArgumentException( "Type definition name is null: " + typeDefinition.getTypeImplementorClass().getName() ); } - final TypeDefinition previous = typeDefinitionMap.put( typeDefinition.getName(), typeDefinition ); + + // Need to register both by name and registration keys. + addTypeDefinition( typeDefinition.getName(), typeDefinition ); + for ( String registrationKey : typeDefinition.getRegistrationKeys() ) { + addTypeDefinition( registrationKey, typeDefinition ); + } + } + + private void addTypeDefinition( String registrationKey, + TypeDefinition typeDefinition ) { + final TypeDefinition previous = typeDefinitionMap.put( + registrationKey, typeDefinition ); if ( previous != null ) { - LOG.debugf( "Duplicate typedef name [%s] now -> %s", typeDefinition.getName(), typeDefinition.getTypeImplementorClass().getName() ); + LOG.debugf( "Duplicate typedef name [%s] now -> %s", + registrationKey, + typeDefinition.getTypeImplementorClass().getName() ); } } @@ -246,8 +258,13 @@ public class MetadataImpl implements MetadataImplementor, Serializable { } @Override - public TypeDefinition getTypeDefinition(String name) { - return typeDefinitionMap.get( name ); + public boolean hasTypeDefinition(String registrationKey) { + return typeDefinitionMap.containsKey( registrationKey ); + } + + @Override + public TypeDefinition getTypeDefinition(String registrationKey) { + return typeDefinitionMap.get( registrationKey ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ExplicitHibernateTypeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ExplicitHibernateTypeSourceImpl.java index e7ec9269a6..4b48f3c67a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ExplicitHibernateTypeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ExplicitHibernateTypeSourceImpl.java @@ -25,16 +25,16 @@ package org.hibernate.metamodel.internal.source.annotations; import java.util.Map; -import org.hibernate.metamodel.internal.source.annotations.attribute.AssociationAttribute; +import org.hibernate.metamodel.internal.source.annotations.attribute.MappedAttribute; import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource; /** * @author Hardy Ferentschik */ public class ExplicitHibernateTypeSourceImpl implements ExplicitHibernateTypeSource { - private final AssociationAttribute attribute; + private final MappedAttribute attribute; - public ExplicitHibernateTypeSourceImpl(AssociationAttribute attribute) { + public ExplicitHibernateTypeSourceImpl(MappedAttribute attribute) { this.attribute = attribute; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/SingularAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/SingularAttributeSourceImpl.java index 3ec4c35b90..9a2a250481 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/SingularAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/SingularAttributeSourceImpl.java @@ -31,7 +31,6 @@ import org.hibernate.mapping.PropertyGeneration; import org.hibernate.metamodel.internal.source.annotations.attribute.AttributeOverride; import org.hibernate.metamodel.internal.source.annotations.attribute.Column; import org.hibernate.metamodel.internal.source.annotations.attribute.MappedAttribute; -import org.hibernate.metamodel.internal.source.annotations.attribute.type.ExplicitHibernateTypeSourceImpl; import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource; import org.hibernate.metamodel.spi.source.MetaAttributeSource; @@ -56,7 +55,7 @@ public class SingularAttributeSourceImpl implements SingularAttributeSource { @Override public ExplicitHibernateTypeSource getTypeInformation() { - return new ExplicitHibernateTypeSourceImpl( attribute.getHibernateTypeResolver() ); + return new ExplicitHibernateTypeSourceImpl( attribute ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/AssociationAttribute.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/AssociationAttribute.java index 50fd18c769..58f9529e1c 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/AssociationAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/AssociationAttribute.java @@ -219,7 +219,7 @@ public class AssociationAttribute extends MappedAttribute { } private AttributeTypeResolver getDefaultHibernateTypeResolver() { - return new CompositeAttributeTypeResolver( new AttributeTypeResolverImpl( this ) ); + return new CompositeAttributeTypeResolver( this, new AttributeTypeResolverImpl( this ) ); } private boolean determineNotFoundBehavior() { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/BasicAttribute.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/BasicAttribute.java index 09932c6310..375375645e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/BasicAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/BasicAttribute.java @@ -409,11 +409,8 @@ public class BasicAttribute extends MappedAttribute { } private AttributeTypeResolver getDefaultHibernateTypeResolver() { - CompositeAttributeTypeResolver resolver = new CompositeAttributeTypeResolver( - new AttributeTypeResolverImpl( - this - ) - ); + CompositeAttributeTypeResolver resolver = new CompositeAttributeTypeResolver( this ); + resolver.addHibernateTypeResolver( new AttributeTypeResolverImpl( this ) ); resolver.addHibernateTypeResolver( new TemporalTypeResolver( this ) ); resolver.addHibernateTypeResolver( new LobTypeResolver( this ) ); resolver.addHibernateTypeResolver( new EnumeratedTypeResolver( this ) ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/AbstractAttributeTypeResolver.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/AbstractAttributeTypeResolver.java index f634756edd..b8451afd37 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/AbstractAttributeTypeResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/AbstractAttributeTypeResolver.java @@ -27,34 +27,62 @@ package org.hibernate.metamodel.internal.source.annotations.attribute.type; import java.util.Collections; import java.util.Map; -import org.jboss.jandex.AnnotationInstance; - import org.hibernate.internal.util.StringHelper; +import org.hibernate.metamodel.internal.source.annotations.attribute.MappedAttribute; +import org.jboss.jandex.AnnotationInstance; /** * @author Strong Liu + * @author Brett Meyer */ public abstract class AbstractAttributeTypeResolver implements AttributeTypeResolver { - protected abstract AnnotationInstance getTypeDeterminingAnnotationInstance(); + + protected final MappedAttribute mappedAttribute; - protected abstract String resolveHibernateTypeName(AnnotationInstance annotationInstance); - - protected Map resolveHibernateTypeParameters(AnnotationInstance annotationInstance) { - return Collections.emptyMap(); + public AbstractAttributeTypeResolver( MappedAttribute mappedAttribute ) { + this.mappedAttribute = mappedAttribute; } - + @Override final public String getExplicitHibernateTypeName() { - return resolveHibernateTypeName( getTypeDeterminingAnnotationInstance() ); + String type = getExplicitAnnotatedHibernateTypeName(); + // If the attribute is annotated with a type, use it. Otherwise, + // check for a @TypeDef. + if ( !StringHelper.isEmpty( type ) ) { + return type; + } else { + return hasEntityTypeDef() ? mappedAttribute.getAttributeType().getName() : null; + } + } + + @Override + final public String getExplicitAnnotatedHibernateTypeName() { + return resolveAnnotatedHibernateTypeName( + getTypeDeterminingAnnotationInstance() ); } @Override final public Map getExplicitHibernateTypeParameters() { if ( StringHelper.isNotEmpty( getExplicitHibernateTypeName() ) ) { - return resolveHibernateTypeParameters( getTypeDeterminingAnnotationInstance() ); + return resolveHibernateTypeParameters( + getTypeDeterminingAnnotationInstance() ); } else { return Collections.emptyMap(); } } + + final protected boolean hasEntityTypeDef() { + return mappedAttribute.getContext() + .getMetadataImplementor().hasTypeDefinition( + mappedAttribute.getAttributeType().getName() ); + } + + protected abstract AnnotationInstance getTypeDeterminingAnnotationInstance(); + + protected abstract String resolveAnnotatedHibernateTypeName(AnnotationInstance annotationInstance); + + protected Map resolveHibernateTypeParameters(AnnotationInstance annotationInstance) { + return Collections.emptyMap(); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/AttributeTypeResolver.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/AttributeTypeResolver.java index b332c19e5a..96d709e5f3 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/AttributeTypeResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/AttributeTypeResolver.java @@ -41,6 +41,8 @@ public interface AttributeTypeResolver { * {@link javax.persistence.Temporal}. */ String getExplicitHibernateTypeName(); + + String getExplicitAnnotatedHibernateTypeName(); /** * @return Returns a map of optional type parameters. See {@link #getExplicitHibernateTypeName()}. diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/AttributeTypeResolverImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/AttributeTypeResolverImpl.java index 4ca0cbd463..e4545a6298 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/AttributeTypeResolverImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/AttributeTypeResolverImpl.java @@ -38,32 +38,42 @@ import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper; * Type Resolver which checks {@link org.hibernate.annotations.Type} to find the type info. * * @author Strong Liu + * @author Brett Meyer */ public class AttributeTypeResolverImpl extends AbstractAttributeTypeResolver { - private final MappedAttribute mappedAttribute; - + public AttributeTypeResolverImpl(MappedAttribute mappedAttribute) { - this.mappedAttribute = mappedAttribute; + super( mappedAttribute ); } @Override - protected String resolveHibernateTypeName(AnnotationInstance typeAnnotation) { - return typeAnnotation != null ? JandexHelper.getValue( typeAnnotation, "type", String.class ) : null; + protected String resolveAnnotatedHibernateTypeName(AnnotationInstance typeAnnotation) { + if ( typeAnnotation != null ) { + return JandexHelper.getValue( + typeAnnotation, "type", String.class ); + } + else { + return null; + } } @Override protected Map resolveHibernateTypeParameters(AnnotationInstance typeAnnotation) { HashMap typeParameters = new HashMap(); - AnnotationValue parameterAnnotationValue = typeAnnotation.value( "parameters" ); - if ( parameterAnnotationValue != null ) { - AnnotationInstance[] parameterAnnotations = parameterAnnotationValue.asNestedArray(); - for ( AnnotationInstance parameterAnnotationInstance : parameterAnnotations ) { - typeParameters.put( - JandexHelper.getValue( parameterAnnotationInstance, "name", String.class ), - JandexHelper.getValue( parameterAnnotationInstance, "value", String.class ) - ); + + if ( typeAnnotation != null ) { + AnnotationValue parameterAnnotationValue = typeAnnotation.value( "parameters" ); + if ( parameterAnnotationValue != null ) { + AnnotationInstance[] parameterAnnotations = parameterAnnotationValue.asNestedArray(); + for ( AnnotationInstance parameterAnnotationInstance : parameterAnnotations ) { + typeParameters.put( + JandexHelper.getValue( parameterAnnotationInstance, "name", String.class ), + JandexHelper.getValue( parameterAnnotationInstance, "value", String.class ) + ); + } } } + return typeParameters; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/CompositeAttributeTypeResolver.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/CompositeAttributeTypeResolver.java index 2d1a1b3848..46ce87c2fc 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/CompositeAttributeTypeResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/CompositeAttributeTypeResolver.java @@ -25,27 +25,30 @@ package org.hibernate.metamodel.internal.source.annotations.attribute.type; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; import org.hibernate.AssertionFailure; import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.collections.CollectionHelper; +import org.hibernate.metamodel.internal.source.annotations.attribute.MappedAttribute; /** * @author Strong Liu + * @author Brett Meyer */ public class CompositeAttributeTypeResolver implements AttributeTypeResolver { + private final MappedAttribute mappedAttribute; private List resolvers = new ArrayList(); - private final AttributeTypeResolverImpl explicitHibernateTypeResolver; - public CompositeAttributeTypeResolver(AttributeTypeResolverImpl explicitHibernateTypeResolver) { - if ( explicitHibernateTypeResolver == null ) { - throw new AssertionFailure( "The Given AttributeTypeResolver is null." ); - } - this.explicitHibernateTypeResolver = explicitHibernateTypeResolver; + public CompositeAttributeTypeResolver ( MappedAttribute mappedAttribute, + AttributeTypeResolver... resolvers) { + this.mappedAttribute = mappedAttribute; + this.resolvers.addAll( Arrays.asList( resolvers ) ); } - + public void addHibernateTypeResolver(AttributeTypeResolver resolver) { if ( resolver == null ) { throw new AssertionFailure( "The Given AttributeTypeResolver is null." ); @@ -55,29 +58,39 @@ public class CompositeAttributeTypeResolver implements AttributeTypeResolver { @Override public String getExplicitHibernateTypeName() { - String type = explicitHibernateTypeResolver.getExplicitHibernateTypeName(); - if ( StringHelper.isEmpty( type ) ) { - for ( AttributeTypeResolver resolver : resolvers ) { - type = resolver.getExplicitHibernateTypeName(); - if ( StringHelper.isNotEmpty( type ) ) { - break; - } + String type = getExplicitAnnotatedHibernateTypeName(); + if ( StringHelper.isNotEmpty( type ) ) { + return type; + } + else if ( mappedAttribute.getContext() + .getMetadataImplementor().hasTypeDefinition( + mappedAttribute.getAttributeType().getName() ) ) { + return mappedAttribute.getAttributeType().getName(); + } + else { + return null; + } + } + + @Override + public String getExplicitAnnotatedHibernateTypeName() { + for ( AttributeTypeResolver resolver : resolvers ) { + String type = resolver.getExplicitAnnotatedHibernateTypeName(); + if ( StringHelper.isNotEmpty( type ) ) { + return type; } } - return type; + return null; } @Override public Map getExplicitHibernateTypeParameters() { - Map parameters = explicitHibernateTypeResolver.getExplicitHibernateTypeParameters(); - if ( CollectionHelper.isEmpty( parameters ) ) { - for ( AttributeTypeResolver resolver : resolvers ) { - parameters = resolver.getExplicitHibernateTypeParameters(); - if ( CollectionHelper.isNotEmpty( parameters ) ) { - break; - } + for ( AttributeTypeResolver resolver : resolvers ) { + Map parameters = resolver.getExplicitHibernateTypeParameters(); + if ( CollectionHelper.isNotEmpty( parameters ) ) { + return parameters; } } - return parameters; + return Collections.EMPTY_MAP; } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/EnumeratedTypeResolver.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/EnumeratedTypeResolver.java index c6e090db55..ac7ba5ea72 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/EnumeratedTypeResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/EnumeratedTypeResolver.java @@ -28,28 +28,26 @@ import java.sql.Types; import java.util.HashMap; import java.util.Map; -import org.jboss.jandex.AnnotationInstance; - import org.hibernate.AnnotationException; import org.hibernate.AssertionFailure; import org.hibernate.metamodel.internal.source.annotations.attribute.MappedAttribute; import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames; import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper; import org.hibernate.type.EnumType; +import org.jboss.jandex.AnnotationInstance; /** * @author Strong Liu + * @author Brett Meyer */ public class EnumeratedTypeResolver extends AbstractAttributeTypeResolver { - private final MappedAttribute mappedAttribute; private final boolean isMapKey; + private final boolean isEnum; public EnumeratedTypeResolver(MappedAttribute mappedAttribute) { - if ( mappedAttribute == null ) { - throw new AssertionFailure( "MappedAttribute is null" ); - } - this.mappedAttribute = mappedAttribute; - this.isMapKey = false;//todo + super( mappedAttribute ); + isEnum = mappedAttribute.getAttributeType().isEnum(); + isMapKey = false;//todo } @Override @@ -61,17 +59,18 @@ public class EnumeratedTypeResolver extends AbstractAttributeTypeResolver { } @Override - public String resolveHibernateTypeName(AnnotationInstance enumeratedAnnotation) { - boolean isEnum = mappedAttribute.getAttributeType().isEnum(); - if ( !isEnum ) { - if ( enumeratedAnnotation != null ) { + public String resolveAnnotatedHibernateTypeName(AnnotationInstance enumeratedAnnotation) { + if ( enumeratedAnnotation != null ) { + if ( isEnum ) { + return EnumType.class.getName(); + } else { throw new AnnotationException( "Attribute " + mappedAttribute.getName() + " is not a Enumerated type, but has a @Enumerated annotation." ); } - else { - return null; - } + } + else if ( !hasEntityTypeDef() && isEnum ) { + return EnumType.class.getName(); } - return EnumType.class.getName(); + return null; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/ExplicitHibernateTypeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/ExplicitHibernateTypeSourceImpl.java deleted file mode 100644 index 4305183f0d..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/ExplicitHibernateTypeSourceImpl.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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.internal.source.annotations.attribute.type; - -import java.util.Map; - -import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource; - -/** - * @author Strong Liu - */ -public class ExplicitHibernateTypeSourceImpl implements ExplicitHibernateTypeSource { - private final AttributeTypeResolver typeResolver; - - public ExplicitHibernateTypeSourceImpl(AttributeTypeResolver typeResolver) { - this.typeResolver = typeResolver; - } - - @Override - public String getName() { - return typeResolver.getExplicitHibernateTypeName(); - } - - @Override - public Map getParameters() { - return typeResolver.getExplicitHibernateTypeParameters(); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/LobTypeResolver.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/LobTypeResolver.java index dcf38be7a0..35135673e6 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/LobTypeResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/LobTypeResolver.java @@ -30,9 +30,6 @@ import java.sql.Clob; import java.util.HashMap; import java.util.Map; -import org.jboss.jandex.AnnotationInstance; - -import org.hibernate.AssertionFailure; import org.hibernate.metamodel.internal.source.annotations.attribute.MappedAttribute; import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames; import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper; @@ -41,18 +38,16 @@ import org.hibernate.type.PrimitiveCharacterArrayClobType; import org.hibernate.type.SerializableToBlobType; import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.WrappedMaterializedBlobType; +import org.jboss.jandex.AnnotationInstance; /** * @author Strong Liu + * @author Brett Meyer */ public class LobTypeResolver extends AbstractAttributeTypeResolver { - private final MappedAttribute mappedAttribute; public LobTypeResolver(MappedAttribute mappedAttribute) { - if ( mappedAttribute == null ) { - throw new AssertionFailure( "MappedAttribute is null" ); - } - this.mappedAttribute = mappedAttribute; + super( mappedAttribute ); } @Override @@ -61,7 +56,7 @@ public class LobTypeResolver extends AbstractAttributeTypeResolver { } @Override - public String resolveHibernateTypeName(AnnotationInstance annotationInstance) { + public String resolveAnnotatedHibernateTypeName(AnnotationInstance annotationInstance) { if ( annotationInstance == null ) { return null; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/TemporalTypeResolver.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/TemporalTypeResolver.java index 69bb40ad7c..1ae04686e2 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/TemporalTypeResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/type/TemporalTypeResolver.java @@ -44,23 +44,22 @@ import org.jboss.jandex.AnnotationInstance; * @author Brett Meyer */ public class TemporalTypeResolver extends AbstractAttributeTypeResolver { - private final BasicAttribute mappedAttribute; + private final BasicAttribute basicAttribute; private final boolean isMapKey; + public TemporalTypeResolver(BasicAttribute mappedAttribute) { - if ( mappedAttribute == null ) { - throw new AssertionFailure( "MappedAttribute is null" ); - } - this.mappedAttribute = mappedAttribute; + super( mappedAttribute ); + this.basicAttribute = mappedAttribute; this.isMapKey = false;//todo } @Override - public String resolveHibernateTypeName(AnnotationInstance temporalAnnotation) { + public String resolveAnnotatedHibernateTypeName(AnnotationInstance temporalAnnotation) { Class attributeType = mappedAttribute.getAttributeType(); if ( isTemporalType( attributeType ) ) { - if ( mappedAttribute.isVersioned() && mappedAttribute.getVersionSourceType() != null ) { - return mappedAttribute.getVersionSourceType().typeName(); + if ( basicAttribute.isVersioned() && basicAttribute.getVersionSourceType() != null ) { + return basicAttribute.getVersionSourceType().typeName(); } if ( temporalAnnotation == null ) { // Although JPA 2.1 states that @Temporal is required on diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/enumerated/EnumeratedTypeTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/enumerated/EnumeratedTypeTest.java index bf7a6bd7c9..648ba76369 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/enumerated/EnumeratedTypeTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/enumerated/EnumeratedTypeTest.java @@ -7,13 +7,12 @@ import java.io.Serializable; import org.hibernate.Session; import org.hibernate.criterion.Restrictions; import org.hibernate.metamodel.spi.binding.EntityBinding; +import org.hibernate.metamodel.spi.binding.HibernateTypeDescriptor; import org.hibernate.test.annotations.enumerated.EntityEnum.Common; import org.hibernate.test.annotations.enumerated.EntityEnum.FirstLetter; import org.hibernate.test.annotations.enumerated.EntityEnum.LastNumber; -import org.hibernate.testing.FailureExpectedWithNewMetamodel; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.type.EnumType; -import org.hibernate.type.Type; import org.junit.Test; /** @@ -21,7 +20,6 @@ import org.junit.Test; * * @author Janario Oliveira */ -@FailureExpectedWithNewMetamodel public class EnumeratedTypeTest extends BaseCoreFunctionalTestCase { @Test @@ -29,34 +27,46 @@ public class EnumeratedTypeTest extends BaseCoreFunctionalTestCase { EntityBinding binding = getEntityBinding( EntityEnum.class ); // ordinal default of EnumType - Type ordinalEnum = binding.locateAttributeBinding( "ordinal" ) - .getHibernateTypeDescriptor().getResolvedTypeMapping(); - assertEquals( Common.class, ordinalEnum.getReturnedClass() ); - assertEquals( EnumType.class.getName(), ordinalEnum.getName() ); + HibernateTypeDescriptor ordinalEnum = binding + .locateAttributeBinding( "ordinal" ) + .getHibernateTypeDescriptor(); + assertEquals( Common.class, ordinalEnum.getResolvedTypeMapping() + .getReturnedClass() ); + assertEquals( EnumType.class.getName(), ordinalEnum.getExplicitTypeName() ); // string defined by Enumerated(STRING) - Type stringEnum = binding.locateAttributeBinding( "string" ) - .getHibernateTypeDescriptor().getResolvedTypeMapping(); - assertEquals( Common.class, stringEnum.getReturnedClass() ); - assertEquals( EnumType.class.getName(), stringEnum.getName() ); + HibernateTypeDescriptor stringEnum = binding + .locateAttributeBinding( "string" ) + .getHibernateTypeDescriptor(); + assertEquals( Common.class, stringEnum.getResolvedTypeMapping() + .getReturnedClass() ); + assertEquals( EnumType.class.getName(), stringEnum.getExplicitTypeName() ); // explicit defined by @Type - Type first = binding.locateAttributeBinding( "firstLetter" ) - .getHibernateTypeDescriptor().getResolvedTypeMapping(); - assertEquals( FirstLetter.class, first.getReturnedClass() ); - assertEquals( FirstLetterType.class.getName(), first.getName() ); + HibernateTypeDescriptor first = binding + .locateAttributeBinding( "firstLetter" ) + .getHibernateTypeDescriptor(); + assertEquals( FirstLetter.class, first.getResolvedTypeMapping() + .getReturnedClass() ); + assertEquals( FirstLetterType.class.getName(), first.getExplicitTypeName() ); // implicit defined by @TypeDef in somewhere - Type last = binding.locateAttributeBinding( "lastNumber" ) - .getHibernateTypeDescriptor().getResolvedTypeMapping(); - assertEquals( LastNumber.class, last.getReturnedClass() ); - assertEquals( LastNumberType.class.getName(), last.getName() ); + HibernateTypeDescriptor last = binding + .locateAttributeBinding( "lastNumber" ) + .getHibernateTypeDescriptor(); + assertEquals( LastNumber.class, last.getResolvedTypeMapping() + .getReturnedClass() ); + assertEquals( LastNumberType.class.getName(), last.getExplicitTypeName() ); // implicit defined by @TypeDef in anywhere, but overrided by Enumerated(STRING) - Type implicitOverrideExplicit = binding.locateAttributeBinding( "explicitOverridingImplicit" ) - .getHibernateTypeDescriptor().getResolvedTypeMapping(); - assertEquals( LastNumber.class, implicitOverrideExplicit.getReturnedClass() ); - assertEquals( EnumType.class.getName(), implicitOverrideExplicit.getName() ); + HibernateTypeDescriptor implicitOverrideExplicit = binding + .locateAttributeBinding( "explicitOverridingImplicit" ) + .getHibernateTypeDescriptor(); + assertEquals( LastNumber.class, + implicitOverrideExplicit.getResolvedTypeMapping() + .getReturnedClass() ); + assertEquals( EnumType.class.getName(), + implicitOverrideExplicit.getExplicitTypeName() ); } @Test