HHH-7123 HHH-7124 : Many-to-one attribute domain and relational models
This commit is contained in:
parent
0eebaf4fe1
commit
6bab3a3141
|
@ -36,6 +36,7 @@ import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.cfg.NamingStrategy;
|
import org.hibernate.cfg.NamingStrategy;
|
||||||
import org.hibernate.cfg.NotYetImplementedException;
|
import org.hibernate.cfg.NotYetImplementedException;
|
||||||
import org.hibernate.cfg.ObjectNameNormalizer;
|
import org.hibernate.cfg.ObjectNameNormalizer;
|
||||||
|
import org.hibernate.engine.FetchTiming;
|
||||||
import org.hibernate.id.IdentifierGenerator;
|
import org.hibernate.id.IdentifierGenerator;
|
||||||
import org.hibernate.id.PersistentIdentifierGenerator;
|
import org.hibernate.id.PersistentIdentifierGenerator;
|
||||||
import org.hibernate.id.factory.IdentifierGeneratorFactory;
|
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.persister.entity.EntityPersister;
|
||||||
import org.hibernate.service.config.spi.ConfigurationService;
|
import org.hibernate.service.config.spi.ConfigurationService;
|
||||||
import org.hibernate.tuple.entity.EntityTuplizer;
|
import org.hibernate.tuple.entity.EntityTuplizer;
|
||||||
|
import org.hibernate.type.EntityType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -230,12 +232,17 @@ public class Binder {
|
||||||
attributeSource.isLazy(),
|
attributeSource.isLazy(),
|
||||||
createMetaAttributeContext( attributeBindingContainer, attributeSource ),
|
createMetaAttributeContext( attributeBindingContainer, attributeSource ),
|
||||||
attributeSource.getGeneration() );
|
attributeSource.getGeneration() );
|
||||||
bindHibernateTypeDescriptor(
|
|
||||||
attributeBinding.getHibernateTypeDescriptor(),
|
|
||||||
attributeSource.getTypeInformation(),
|
|
||||||
attributeBinding.getAttribute(),
|
|
||||||
( AbstractValue ) relationalValueBindings.get( 0 ).getValue() );
|
|
||||||
final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding.getHibernateTypeDescriptor();
|
final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding.getHibernateTypeDescriptor();
|
||||||
|
bindHibernateTypeDescriptor(
|
||||||
|
hibernateTypeDescriptor,
|
||||||
|
attributeSource.getTypeInformation(),
|
||||||
|
attributeBinding.getAttribute()
|
||||||
|
);
|
||||||
|
resolveHibernateResolvedType(
|
||||||
|
attributeBinding.getHibernateTypeDescriptor(),
|
||||||
|
getHeuristicType( hibernateTypeDescriptor ),
|
||||||
|
( AbstractValue ) relationalValueBindings.get( 0 ).getValue()
|
||||||
|
);
|
||||||
attributeBinding.getAttribute().resolveType(
|
attributeBinding.getAttribute().resolveType(
|
||||||
bindingContexts.peek().makeJavaType( hibernateTypeDescriptor.getJavaTypeName() ) );
|
bindingContexts.peek().makeJavaType( hibernateTypeDescriptor.getJavaTypeName() ) );
|
||||||
return attributeBinding;
|
return attributeBinding;
|
||||||
|
@ -515,7 +522,10 @@ public class Binder {
|
||||||
: "string";
|
: "string";
|
||||||
final HibernateTypeDescriptor hibernateTypeDescriptor = discriminator.getExplicitHibernateTypeDescriptor();
|
final HibernateTypeDescriptor hibernateTypeDescriptor = discriminator.getExplicitHibernateTypeDescriptor();
|
||||||
hibernateTypeDescriptor.setExplicitTypeName( typeName );
|
hibernateTypeDescriptor.setExplicitTypeName( typeName );
|
||||||
resolveHibernateResolvedType( hibernateTypeDescriptor, typeName, value );
|
resolveHibernateResolvedType(
|
||||||
|
hibernateTypeDescriptor,
|
||||||
|
getHeuristicType( hibernateTypeDescriptor ),
|
||||||
|
value );
|
||||||
}
|
}
|
||||||
|
|
||||||
private EntityBinding bindEntities( final EntityHierarchy entityHierarchy ) {
|
private EntityBinding bindEntities( final EntityHierarchy entityHierarchy ) {
|
||||||
|
@ -587,17 +597,12 @@ public class Binder {
|
||||||
private void bindHibernateTypeDescriptor(
|
private void bindHibernateTypeDescriptor(
|
||||||
final HibernateTypeDescriptor hibernateTypeDescriptor,
|
final HibernateTypeDescriptor hibernateTypeDescriptor,
|
||||||
final ExplicitHibernateTypeSource typeSource,
|
final ExplicitHibernateTypeSource typeSource,
|
||||||
final Attribute attribute,
|
final Attribute attribute) {
|
||||||
final AbstractValue value ) {
|
|
||||||
String typeName = typeSource.getName();
|
String typeName = typeSource.getName();
|
||||||
// Check if user specified a type
|
// Check if user specified a type
|
||||||
if ( typeName == null ) {
|
if ( typeName == null ) {
|
||||||
// Obtain Java type name from attribute
|
// Obtain Java type name from attribute
|
||||||
final Class< ? > attributeJavaType =
|
typeName = determineJavaType( attribute ).getName();
|
||||||
ReflectHelper.reflectedPropertyClass(
|
|
||||||
attribute.getAttributeContainer().getClassReference(),
|
|
||||||
attribute.getName() );
|
|
||||||
typeName = attributeJavaType.getName();
|
|
||||||
hibernateTypeDescriptor.setJavaTypeName( typeName );
|
hibernateTypeDescriptor.setJavaTypeName( typeName );
|
||||||
} else {
|
} else {
|
||||||
// Check if user-specified name is of a User-Defined Type (UDT)
|
// Check if user-specified name is of a User-Defined Type (UDT)
|
||||||
|
@ -613,9 +618,15 @@ public class Binder {
|
||||||
hibernateTypeDescriptor.getTypeParameters().putAll( typeParameters );
|
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 ) {
|
private void bindIdentifier( final EntityBinding rootEntityBinding, final IdentifierSource identifierSource ) {
|
||||||
final Nature nature = identifierSource.getNature();
|
final Nature nature = identifierSource.getNature();
|
||||||
if ( nature == Nature.SIMPLE ) {
|
if ( nature == Nature.SIMPLE ) {
|
||||||
|
@ -642,6 +653,7 @@ public class Binder {
|
||||||
if ( attribute == null ) {
|
if ( attribute == null ) {
|
||||||
attribute = createSingularAttribute( attributeBindingContainer, attributeSource );
|
attribute = createSingularAttribute( attributeBindingContainer, attributeSource );
|
||||||
}
|
}
|
||||||
|
// TODO: figure out which table is used (could be secondary table...)
|
||||||
final List< RelationalValueBinding > relationalValueBindings =
|
final List< RelationalValueBinding > relationalValueBindings =
|
||||||
bindValues(
|
bindValues(
|
||||||
attributeBindingContainer,
|
attributeBindingContainer,
|
||||||
|
@ -650,7 +662,7 @@ public class Binder {
|
||||||
attributeBindingContainer.seekEntityBinding().getPrimaryTable() );
|
attributeBindingContainer.seekEntityBinding().getPrimaryTable() );
|
||||||
final String referencedEntityName = attributeSource.getReferencedEntityName() != null
|
final String referencedEntityName = attributeSource.getReferencedEntityName() != null
|
||||||
? attributeSource.getReferencedEntityName()
|
? attributeSource.getReferencedEntityName()
|
||||||
: HibernateTypeHelper.determineJavaType( attribute ).getName();
|
: determineJavaType( attribute ).getName();
|
||||||
final EntityBinding referencedEntityBinding = entityBinding( referencedEntityName );
|
final EntityBinding referencedEntityBinding = entityBinding( referencedEntityName );
|
||||||
final AttributeBinding referencedAttributeBinding =
|
final AttributeBinding referencedAttributeBinding =
|
||||||
attributeSource.getReferencedEntityAttributeName() == null
|
attributeSource.getReferencedEntityAttributeName() == null
|
||||||
|
@ -668,19 +680,33 @@ public class Binder {
|
||||||
relationalValueBindings );
|
relationalValueBindings );
|
||||||
// TODO: is this needed?
|
// TODO: is this needed?
|
||||||
referencedAttributeBinding.addEntityReferencingAttributeBinding( attributeBinding );
|
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(
|
bindHibernateTypeDescriptor(
|
||||||
attributeBinding.getHibernateTypeDescriptor(),
|
attributeBinding.getHibernateTypeDescriptor(),
|
||||||
attributeSource.getTypeInformation(),
|
attributeSource.getTypeInformation(),
|
||||||
attributeBinding.getAttribute(),
|
attributeBinding.getAttribute()
|
||||||
( AbstractValue ) relationalValueBindings.get( 0 ).getValue() );
|
);
|
||||||
|
resolveHibernateResolvedType(
|
||||||
|
attributeBinding.getHibernateTypeDescriptor(),
|
||||||
|
resolvedType,
|
||||||
|
(AbstractValue) relationalValueBindings.get( 0 ).getValue()
|
||||||
|
);
|
||||||
attributeBinding.setCascadeStyles( attributeSource.getCascadeStyles() );
|
attributeBinding.setCascadeStyles( attributeSource.getCascadeStyles() );
|
||||||
attributeBinding.setFetchTiming( attributeSource.getFetchTiming() );
|
attributeBinding.setFetchTiming( attributeSource.getFetchTiming() );
|
||||||
attributeBinding.setFetchStyle( attributeSource.getFetchStyle() );
|
attributeBinding.setFetchStyle( attributeSource.getFetchStyle() );
|
||||||
|
|
||||||
typeHelper.bindManyToOneAttributeTypeInformation(
|
|
||||||
attributeSource,
|
|
||||||
attributeBinding
|
|
||||||
);
|
|
||||||
return attributeBinding;
|
return attributeBinding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1195,24 +1221,40 @@ public class Binder {
|
||||||
|
|
||||||
private void resolveHibernateResolvedType(
|
private void resolveHibernateResolvedType(
|
||||||
final HibernateTypeDescriptor hibernateTypeDescriptor,
|
final HibernateTypeDescriptor hibernateTypeDescriptor,
|
||||||
final String typeName,
|
final Type resolvedType,
|
||||||
final AbstractValue value ) {
|
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
|
// Configure relational value JDBC type from Hibernate type descriptor now that its configured
|
||||||
if ( resolvedType != null ) {
|
if ( resolvedType != null ) {
|
||||||
hibernateTypeDescriptor.setResolvedTypeMapping( resolvedType );
|
hibernateTypeDescriptor.setResolvedTypeMapping( resolvedType );
|
||||||
if ( hibernateTypeDescriptor.getJavaTypeName() == null ) {
|
if ( hibernateTypeDescriptor.getJavaTypeName() == null ) {
|
||||||
hibernateTypeDescriptor.setJavaTypeName( resolvedType.getReturnedClass().getName() );
|
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(
|
value.setJdbcDataType( new JdbcDataType(
|
||||||
resolvedType.sqlTypes( metadata )[ 0 ],
|
resolvedRelationalType.sqlTypes( metadata )[ 0 ],
|
||||||
resolvedType.getName(),
|
resolvedRelationalType.getName(),
|
||||||
resolvedType.getReturnedClass() ) );
|
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 ) {
|
private boolean toBoolean( final TruthValue truthValue, final boolean truthValueDefault ) {
|
||||||
if ( truthValue == TruthValue.TRUE ) {
|
if ( truthValue == TruthValue.TRUE ) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -42,10 +42,8 @@ import org.hibernate.metamodel.spi.binding.AttributeBinding;
|
||||||
import org.hibernate.metamodel.spi.binding.BasicAttributeBinding;
|
import org.hibernate.metamodel.spi.binding.BasicAttributeBinding;
|
||||||
import org.hibernate.metamodel.spi.binding.BasicPluralAttributeElementBinding;
|
import org.hibernate.metamodel.spi.binding.BasicPluralAttributeElementBinding;
|
||||||
import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding;
|
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.HibernateTypeDescriptor;
|
||||||
import org.hibernate.metamodel.spi.binding.IndexedPluralAttributeBinding;
|
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.PluralAttributeBinding;
|
||||||
import org.hibernate.metamodel.spi.binding.PluralAttributeElementBinding;
|
import org.hibernate.metamodel.spi.binding.PluralAttributeElementBinding;
|
||||||
import org.hibernate.metamodel.spi.binding.PluralAttributeElementNature;
|
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.RelationalValueBinding;
|
||||||
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
|
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
|
||||||
import org.hibernate.metamodel.spi.binding.TypeDefinition;
|
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.PluralAttribute;
|
||||||
import org.hibernate.metamodel.spi.domain.SingularAttribute;
|
import org.hibernate.metamodel.spi.domain.SingularAttribute;
|
||||||
import org.hibernate.metamodel.spi.relational.AbstractValue;
|
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.PluralAttributeElementSource;
|
||||||
import org.hibernate.metamodel.spi.source.PluralAttributeSource;
|
import org.hibernate.metamodel.spi.source.PluralAttributeSource;
|
||||||
import org.hibernate.metamodel.spi.source.SingularAttributeSource;
|
import org.hibernate.metamodel.spi.source.SingularAttributeSource;
|
||||||
import org.hibernate.metamodel.spi.source.ToOneAttributeSource;
|
|
||||||
import org.hibernate.type.ComponentType;
|
import org.hibernate.type.ComponentType;
|
||||||
import org.hibernate.type.EntityType;
|
import org.hibernate.type.EntityType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
@ -138,44 +134,6 @@ public class HibernateTypeHelper {
|
||||||
processSingularAttributeTypeInformation( attributeSource, attributeBinding );
|
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(
|
public void bindPluralAttributeTypeInformation(
|
||||||
PluralAttributeSource attributeSource,
|
PluralAttributeSource attributeSource,
|
||||||
PluralAttributeBinding attributeBinding) {
|
PluralAttributeBinding attributeBinding) {
|
||||||
|
@ -260,8 +218,7 @@ public class HibernateTypeHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package-protected */
|
private Class<?> determineJavaType(final SingularAttribute attribute) {
|
||||||
static Class<?> determineJavaType(final SingularAttribute attribute) {
|
|
||||||
try {
|
try {
|
||||||
final Class<?> ownerClass = attribute.getAttributeContainer().getClassReference();
|
final Class<?> ownerClass = attribute.getAttributeContainer().getClassReference();
|
||||||
return ReflectHelper.reflectedPropertyClass( ownerClass, attribute.getName() );
|
return ReflectHelper.reflectedPropertyClass( ownerClass, attribute.getName() );
|
||||||
|
|
Loading…
Reference in New Issue