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 08fb8ee4cd..94ee6c3118 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 @@ -36,6 +36,7 @@ import org.hibernate.cfg.NamingStrategy; import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.cfg.ObjectNameNormalizer; +import org.hibernate.engine.FetchTiming; import org.hibernate.id.IdentifierGenerator; import org.hibernate.id.PersistentIdentifierGenerator; import org.hibernate.id.factory.IdentifierGeneratorFactory; @@ -122,6 +123,7 @@ import org.hibernate.persister.entity.EntityPersister; import org.hibernate.service.config.spi.ConfigurationService; import org.hibernate.tuple.entity.EntityTuplizer; +import org.hibernate.type.EntityType; import org.hibernate.type.Type; /** @@ -230,12 +232,17 @@ private BasicAttributeBinding bindBasicAttribute( attributeSource.isLazy(), createMetaAttributeContext( attributeBindingContainer, attributeSource ), attributeSource.getGeneration() ); - bindHibernateTypeDescriptor( - attributeBinding.getHibernateTypeDescriptor(), - attributeSource.getTypeInformation(), - attributeBinding.getAttribute(), - ( AbstractValue ) relationalValueBindings.get( 0 ).getValue() ); final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding.getHibernateTypeDescriptor(); + bindHibernateTypeDescriptor( + hibernateTypeDescriptor, + attributeSource.getTypeInformation(), + attributeBinding.getAttribute() + ); + resolveHibernateResolvedType( + attributeBinding.getHibernateTypeDescriptor(), + getHeuristicType( hibernateTypeDescriptor ), + ( AbstractValue ) relationalValueBindings.get( 0 ).getValue() + ); attributeBinding.getAttribute().resolveType( bindingContexts.peek().makeJavaType( hibernateTypeDescriptor.getJavaTypeName() ) ); return attributeBinding; @@ -515,7 +522,10 @@ private void bindDiscriminator( final EntityBinding rootEntityBinding, final Roo : "string"; final HibernateTypeDescriptor hibernateTypeDescriptor = discriminator.getExplicitHibernateTypeDescriptor(); hibernateTypeDescriptor.setExplicitTypeName( typeName ); - resolveHibernateResolvedType( hibernateTypeDescriptor, typeName, value ); + resolveHibernateResolvedType( + hibernateTypeDescriptor, + getHeuristicType( hibernateTypeDescriptor ), + value ); } private EntityBinding bindEntities( final EntityHierarchy entityHierarchy ) { @@ -587,17 +597,12 @@ private EntityBinding bindEntity( final EntitySource entitySource, final EntityB private void bindHibernateTypeDescriptor( final HibernateTypeDescriptor hibernateTypeDescriptor, final ExplicitHibernateTypeSource typeSource, - final Attribute attribute, - final AbstractValue value ) { + final Attribute attribute) { String typeName = typeSource.getName(); // Check if user specified a type if ( typeName == null ) { // Obtain Java type name from attribute - final Class< ? > attributeJavaType = - ReflectHelper.reflectedPropertyClass( - attribute.getAttributeContainer().getClassReference(), - attribute.getName() ); - typeName = attributeJavaType.getName(); + typeName = determineJavaType( attribute ).getName(); hibernateTypeDescriptor.setJavaTypeName( typeName ); } else { // Check if user-specified name is of a User-Defined Type (UDT) @@ -613,9 +618,15 @@ private void bindHibernateTypeDescriptor( hibernateTypeDescriptor.getTypeParameters().putAll( typeParameters ); } } - resolveHibernateResolvedType( hibernateTypeDescriptor, typeName, value ); } + private Class determineJavaType(Attribute attribute) { + return ReflectHelper.reflectedPropertyClass( + attribute.getAttributeContainer().getClassReference(), + attribute.getName() + ); + } + private void bindIdentifier( final EntityBinding rootEntityBinding, final IdentifierSource identifierSource ) { final Nature nature = identifierSource.getNature(); if ( nature == Nature.SIMPLE ) { @@ -642,6 +653,7 @@ private ManyToOneAttributeBinding bindManyToOneAttribute( if ( attribute == null ) { attribute = createSingularAttribute( attributeBindingContainer, attributeSource ); } + // TODO: figure out which table is used (could be secondary table...) final List< RelationalValueBinding > relationalValueBindings = bindValues( attributeBindingContainer, @@ -650,7 +662,7 @@ private ManyToOneAttributeBinding bindManyToOneAttribute( attributeBindingContainer.seekEntityBinding().getPrimaryTable() ); final String referencedEntityName = attributeSource.getReferencedEntityName() != null ? attributeSource.getReferencedEntityName() - : HibernateTypeHelper.determineJavaType( attribute ).getName(); + : determineJavaType( attribute ).getName(); final EntityBinding referencedEntityBinding = entityBinding( referencedEntityName ); final AttributeBinding referencedAttributeBinding = attributeSource.getReferencedEntityAttributeName() == null @@ -668,19 +680,33 @@ private ManyToOneAttributeBinding bindManyToOneAttribute( relationalValueBindings ); // TODO: is this needed? referencedAttributeBinding.addEntityReferencingAttributeBinding( attributeBinding ); + if ( ! attribute.isTypeResolved() ) { + attribute.resolveType( referencedEntityBinding.getEntity() ); + } + Type resolvedType = metadata.getTypeResolver().getTypeFactory().manyToOne( + attributeBinding.getReferencedEntityName(), + ( attributeBinding.isPropertyReference() ? attributeBinding.getReferencedAttributeName() : null ), + attributeBinding.getFetchTiming() != FetchTiming.IMMEDIATE, + attributeBinding.getFetchTiming() == FetchTiming.DELAYED, + true, //TODO: is isEmbedded() obsolete? + false, //TODO: should be attributeBinding.isIgnoreNotFound(), + false //TODO: determine if isLogicalOneToOne + ); + // TODO: need to be able to deal with composite IDs bindHibernateTypeDescriptor( - attributeBinding.getHibernateTypeDescriptor(), - attributeSource.getTypeInformation(), - attributeBinding.getAttribute(), - ( AbstractValue ) relationalValueBindings.get( 0 ).getValue() ); + attributeBinding.getHibernateTypeDescriptor(), + attributeSource.getTypeInformation(), + attributeBinding.getAttribute() + ); + resolveHibernateResolvedType( + attributeBinding.getHibernateTypeDescriptor(), + resolvedType, + (AbstractValue) relationalValueBindings.get( 0 ).getValue() + ); attributeBinding.setCascadeStyles( attributeSource.getCascadeStyles() ); attributeBinding.setFetchTiming( attributeSource.getFetchTiming() ); attributeBinding.setFetchStyle( attributeSource.getFetchStyle() ); - typeHelper.bindManyToOneAttributeTypeInformation( - attributeSource, - attributeBinding - ); return attributeBinding; } @@ -1195,24 +1221,40 @@ private String quotedIdentifier( final String name ) { private void resolveHibernateResolvedType( final HibernateTypeDescriptor hibernateTypeDescriptor, - final String typeName, + final Type resolvedType, final AbstractValue value ) { - final Properties typeProperties = new Properties(); - typeProperties.putAll( hibernateTypeDescriptor.getTypeParameters() ); - final Type resolvedType = metadata.getTypeResolver().heuristicType( typeName, typeProperties ); // Configure relational value JDBC type from Hibernate type descriptor now that its configured if ( resolvedType != null ) { hibernateTypeDescriptor.setResolvedTypeMapping( resolvedType ); if ( hibernateTypeDescriptor.getJavaTypeName() == null ) { hibernateTypeDescriptor.setJavaTypeName( resolvedType.getReturnedClass().getName() ); } + Type resolvedRelationalType; + if ( resolvedType.isEntityType() ) { + resolvedRelationalType = EntityType.class.cast( resolvedType ).getIdentifierOrUniqueKeyType( metadata ); + hibernateTypeDescriptor.setToOne( true ); + } + else { + resolvedRelationalType = resolvedType; + hibernateTypeDescriptor.setToOne( false ); + } value.setJdbcDataType( new JdbcDataType( - resolvedType.sqlTypes( metadata )[ 0 ], - resolvedType.getName(), - resolvedType.getReturnedClass() ) ); + resolvedRelationalType.sqlTypes( metadata )[ 0 ], + resolvedRelationalType.getName(), + resolvedRelationalType.getReturnedClass() ) ); } } + private Type getHeuristicType(HibernateTypeDescriptor hibernateTypeDescriptor) { + final String typeName = + hibernateTypeDescriptor.getExplicitTypeName() != null ? + hibernateTypeDescriptor.getExplicitTypeName() : + hibernateTypeDescriptor.getJavaTypeName(); + final Properties properties = new Properties(); + properties.putAll( hibernateTypeDescriptor.getTypeParameters() ); + return metadata.getTypeResolver().heuristicType( typeName, properties ); + } + private boolean toBoolean( final TruthValue truthValue, final boolean truthValueDefault ) { if ( truthValue == TruthValue.TRUE ) { return true; 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 9391b116a1..d0c52f3cac 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 @@ -42,10 +42,8 @@ import org.hibernate.metamodel.spi.binding.BasicAttributeBinding; import org.hibernate.metamodel.spi.binding.BasicPluralAttributeElementBinding; import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding; -import org.hibernate.metamodel.spi.binding.EntityBinding; import org.hibernate.metamodel.spi.binding.HibernateTypeDescriptor; import org.hibernate.metamodel.spi.binding.IndexedPluralAttributeBinding; -import org.hibernate.metamodel.spi.binding.ManyToOneAttributeBinding; import org.hibernate.metamodel.spi.binding.PluralAttributeBinding; import org.hibernate.metamodel.spi.binding.PluralAttributeElementBinding; import org.hibernate.metamodel.spi.binding.PluralAttributeElementNature; @@ -54,7 +52,6 @@ import org.hibernate.metamodel.spi.binding.RelationalValueBinding; import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.binding.TypeDefinition; -import org.hibernate.metamodel.spi.domain.Entity; import org.hibernate.metamodel.spi.domain.PluralAttribute; import org.hibernate.metamodel.spi.domain.SingularAttribute; import org.hibernate.metamodel.spi.relational.AbstractValue; @@ -69,7 +66,6 @@ import org.hibernate.metamodel.spi.source.PluralAttributeElementSource; import org.hibernate.metamodel.spi.source.PluralAttributeSource; import org.hibernate.metamodel.spi.source.SingularAttributeSource; -import org.hibernate.metamodel.spi.source.ToOneAttributeSource; import org.hibernate.type.ComponentType; import org.hibernate.type.EntityType; import org.hibernate.type.Type; @@ -138,44 +134,6 @@ public void bindSingularAttributeTypeInformation( processSingularAttributeTypeInformation( attributeSource, attributeBinding ); } - public void bindManyToOneAttributeTypeInformation( - ToOneAttributeSource attributeSource, - ManyToOneAttributeBinding attributeBinding) { - final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding.getHibernateTypeDescriptor(); - - if ( ! attributeBinding.getAttribute().isTypeResolved() ) { - EntityBinding referencedEntityBinding = metadata.getEntityBinding( attributeBinding.getReferencedEntityName() ); - Entity referencedEntity = referencedEntityBinding == null ? null : referencedEntityBinding.getEntity(); - if ( referencedEntity != null ) { - attributeBinding.getAttribute().resolveType( referencedEntity ); - } - } - - if ( hibernateTypeDescriptor.getJavaTypeName() == null ) { - hibernateTypeDescriptor.setJavaTypeName( determineJavaType( attributeBinding.getAttribute() ).getName() ); - } - - bindHibernateTypeInformation( attributeSource.getTypeInformation(), true, hibernateTypeDescriptor ); - - if ( attributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping() == null ) { - Type resolvedType = metadata.getTypeResolver().getTypeFactory().manyToOne( - attributeBinding.getReferencedEntityName(), - ( attributeBinding.isPropertyReference() ? attributeBinding.getReferencedAttributeName() : null ), - attributeBinding.getFetchTiming() != FetchTiming.IMMEDIATE, - attributeBinding.getFetchTiming() == FetchTiming.DELAYED, - true, //TODO: is isEmbedded() obsolete? - false, //TODO: should be attributeBinding.isIgnoreNotFound(), - false //TODO: determine if isLogicalOneToOne - ); - - pushHibernateTypeInformationDown( - attributeBinding.getHibernateTypeDescriptor(), - attributeBinding.getRelationalValueBindings(), - resolvedType - ); - } - } - public void bindPluralAttributeTypeInformation( PluralAttributeSource attributeSource, PluralAttributeBinding attributeBinding) { @@ -260,8 +218,7 @@ private void processPluralAttributeKeyInformation(PluralAttributeKeyBinding keyB } } - /* package-protected */ - static Class determineJavaType(final SingularAttribute attribute) { + private Class determineJavaType(final SingularAttribute attribute) { try { final Class ownerClass = attribute.getAttributeContainer().getClassReference(); return ReflectHelper.reflectedPropertyClass( ownerClass, attribute.getName() );