HHH-7123 HHH-7124 : Many-to-one attribute domain and relational models

This commit is contained in:
Gail Badner 2012-03-07 21:26:52 -08:00
parent 0eebaf4fe1
commit 6bab3a3141
2 changed files with 73 additions and 74 deletions

View File

@ -36,6 +36,7 @@ import org.hibernate.cfg.AvailableSettings;
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.collection.CollectionPersister;
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 @@ public class Binder {
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 @@ public class Binder {
: "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 @@ public class Binder {
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,7 +618,13 @@ public class Binder {
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 ) {
@ -642,6 +653,7 @@ public class Binder {
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 @@ public class Binder {
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 @@ public class Binder {
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 @@ public class Binder {
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;

View File

@ -42,10 +42,8 @@ import org.hibernate.metamodel.spi.binding.AttributeBinding;
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.PluralAttributeKeyBinding;
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.MetadataImplementor;
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 class HibernateTypeHelper {
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 @@ public class HibernateTypeHelper {
}
}
/* 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() );