Merge branch 'metamodel' of github.com:hibernate/hibernate-orm into metamodel

This commit is contained in:
John Verhaeg 2012-09-20 08:21:15 -05:00
commit 07405e0f00
7 changed files with 159 additions and 103 deletions

View File

@ -57,7 +57,6 @@ import org.hibernate.metamodel.spi.MetadataImplementor;
import org.hibernate.metamodel.spi.binding.AbstractPluralAttributeBinding; import org.hibernate.metamodel.spi.binding.AbstractPluralAttributeBinding;
import org.hibernate.metamodel.spi.binding.AttributeBinding; import org.hibernate.metamodel.spi.binding.AttributeBinding;
import org.hibernate.metamodel.spi.binding.AttributeBindingContainer; import org.hibernate.metamodel.spi.binding.AttributeBindingContainer;
import org.hibernate.metamodel.spi.binding.BagBinding;
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.BasicPluralAttributeIndexBinding; import org.hibernate.metamodel.spi.binding.BasicPluralAttributeIndexBinding;
@ -70,9 +69,7 @@ import org.hibernate.metamodel.spi.binding.HibernateTypeDescriptor;
import org.hibernate.metamodel.spi.binding.IdGenerator; import org.hibernate.metamodel.spi.binding.IdGenerator;
import org.hibernate.metamodel.spi.binding.IndexedPluralAttributeBinding; import org.hibernate.metamodel.spi.binding.IndexedPluralAttributeBinding;
import org.hibernate.metamodel.spi.binding.InheritanceType; import org.hibernate.metamodel.spi.binding.InheritanceType;
import org.hibernate.metamodel.spi.binding.ListBinding;
import org.hibernate.metamodel.spi.binding.ManyToOneAttributeBinding; import org.hibernate.metamodel.spi.binding.ManyToOneAttributeBinding;
import org.hibernate.metamodel.spi.binding.MapBinding;
import org.hibernate.metamodel.spi.binding.MetaAttribute; import org.hibernate.metamodel.spi.binding.MetaAttribute;
import org.hibernate.metamodel.spi.binding.OneToManyPluralAttributeElementBinding; import org.hibernate.metamodel.spi.binding.OneToManyPluralAttributeElementBinding;
import org.hibernate.metamodel.spi.binding.PluralAttributeBinding; import org.hibernate.metamodel.spi.binding.PluralAttributeBinding;
@ -81,7 +78,6 @@ import org.hibernate.metamodel.spi.binding.PluralAttributeIndexBinding;
import org.hibernate.metamodel.spi.binding.PluralAttributeKeyBinding; 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.SecondaryTable; import org.hibernate.metamodel.spi.binding.SecondaryTable;
import org.hibernate.metamodel.spi.binding.SetBinding;
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.Attribute; import org.hibernate.metamodel.spi.domain.Attribute;
@ -94,7 +90,6 @@ import org.hibernate.metamodel.spi.relational.Column;
import org.hibernate.metamodel.spi.relational.DerivedValue; import org.hibernate.metamodel.spi.relational.DerivedValue;
import org.hibernate.metamodel.spi.relational.ForeignKey; import org.hibernate.metamodel.spi.relational.ForeignKey;
import org.hibernate.metamodel.spi.relational.Identifier; import org.hibernate.metamodel.spi.relational.Identifier;
import org.hibernate.metamodel.spi.relational.JdbcDataType;
import org.hibernate.metamodel.spi.relational.PrimaryKey; import org.hibernate.metamodel.spi.relational.PrimaryKey;
import org.hibernate.metamodel.spi.relational.Schema; import org.hibernate.metamodel.spi.relational.Schema;
import org.hibernate.metamodel.spi.relational.Table; import org.hibernate.metamodel.spi.relational.Table;
@ -119,7 +114,6 @@ import org.hibernate.metamodel.spi.source.InLineViewSource;
import org.hibernate.metamodel.spi.source.IndexedPluralAttributeSource; import org.hibernate.metamodel.spi.source.IndexedPluralAttributeSource;
import org.hibernate.metamodel.spi.source.LocalBindingContext; import org.hibernate.metamodel.spi.source.LocalBindingContext;
import org.hibernate.metamodel.spi.source.MappingDefaults; import org.hibernate.metamodel.spi.source.MappingDefaults;
import org.hibernate.metamodel.spi.source.MappingException;
import org.hibernate.metamodel.spi.source.MetaAttributeContext; import org.hibernate.metamodel.spi.source.MetaAttributeContext;
import org.hibernate.metamodel.spi.source.MetaAttributeSource; import org.hibernate.metamodel.spi.source.MetaAttributeSource;
import org.hibernate.metamodel.spi.source.MultiTenancySource; import org.hibernate.metamodel.spi.source.MultiTenancySource;
@ -148,7 +142,6 @@ import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.tuple.component.ComponentMetamodel; import org.hibernate.tuple.component.ComponentMetamodel;
import org.hibernate.tuple.entity.EntityTuplizer; import org.hibernate.tuple.entity.EntityTuplizer;
import org.hibernate.type.ComponentType; import org.hibernate.type.ComponentType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type; import org.hibernate.type.Type;
import org.hibernate.type.TypeFactory; import org.hibernate.type.TypeFactory;
@ -164,8 +157,7 @@ import static org.hibernate.engine.spi.SyntheticAttributeHelper.SYNTHETIC_COMPOS
* @author Gail Badner * @author Gail Badner
*/ */
public class Binder { public class Binder {
private static final Logger log = Logger.getLogger( Binder.class ); private static final CoreMessageLogger log = Logger.getMessageLogger(
private static final CoreMessageLogger coreLogger = Logger.getMessageLogger(
CoreMessageLogger.class, CoreMessageLogger.class,
Binder.class.getName() Binder.class.getName()
); );
@ -377,7 +369,7 @@ public class Binder {
createSingularAttributeJavaType( attributeBinding.getAttribute() ) ); createSingularAttributeJavaType( attributeBinding.getAttribute() ) );
Type resolvedType = heuristicType( hibernateTypeDescriptor ); Type resolvedType = heuristicType( hibernateTypeDescriptor );
bindHibernateResolvedType( attributeBinding.getHibernateTypeDescriptor(), resolvedType ); bindHibernateResolvedType( attributeBinding.getHibernateTypeDescriptor(), resolvedType );
bindJdbcDataType( resolvedType, ( AbstractValue ) relationalValueBindings.get( 0 ).getValue() ); typeHelper.bindJdbcDataType( resolvedType, ( AbstractValue ) relationalValueBindings.get( 0 ).getValue() );
attributeBinding.getAttribute().resolveType( bindingContext().makeJavaType( hibernateTypeDescriptor.getJavaTypeName() ) ); attributeBinding.getAttribute().resolveType( bindingContext().makeJavaType( hibernateTypeDescriptor.getJavaTypeName() ) );
return attributeBinding; return attributeBinding;
} }
@ -394,9 +386,9 @@ public class Binder {
); );
Type resolvedElementType = heuristicType( elementBinding.getHibernateTypeDescriptor() ); Type resolvedElementType = heuristicType( elementBinding.getHibernateTypeDescriptor() );
bindHibernateResolvedType( elementBinding.getHibernateTypeDescriptor(), resolvedElementType ); bindHibernateResolvedType( elementBinding.getHibernateTypeDescriptor(), resolvedElementType );
bindJdbcDataType( typeHelper.bindJdbcDataType(
resolvedElementType, resolvedElementType,
(AbstractValue) elementBinding.getRelationalValueBindings().get( 0 ).getValue() elementBinding.getRelationalValueBindings().get( 0 ).getValue()
); );
} }
@ -440,9 +432,9 @@ public class Binder {
final BasicPluralAttributeElementBinding elementBinding = final BasicPluralAttributeElementBinding elementBinding =
( BasicPluralAttributeElementBinding ) attributeBinding.getPluralAttributeElementBinding(); ( BasicPluralAttributeElementBinding ) attributeBinding.getPluralAttributeElementBinding();
if ( elementBinding.getNature() != PluralAttributeElementBinding.Nature.BASIC ) { if ( elementBinding.getNature() != PluralAttributeElementBinding.Nature.BASIC ) {
throw new MappingException( String.format( bindingContext().makeMappingException( String.format(
"Expected a SetBinding with an element of nature Nature.BASIC; instead was %s", "Expected a SetBinding with an element of nature Nature.BASIC; instead was %s",
elementBinding.getNature() ), bindingContexts.peek().getOrigin() ); elementBinding.getNature() ) );
} }
if ( hasAnyNonNullableColumns( elementBinding.getRelationalValueBindings() ) ) { if ( hasAnyNonNullableColumns( elementBinding.getRelationalValueBindings() ) ) {
final PrimaryKey primaryKey = attributeBinding.getPluralAttributeKeyBinding().getCollectionTable().getPrimaryKey(); final PrimaryKey primaryKey = attributeBinding.getPluralAttributeKeyBinding().getCollectionTable().getPrimaryKey();
@ -489,7 +481,7 @@ public class Binder {
defaultIndexJavaTypeName ); defaultIndexJavaTypeName );
Type resolvedElementType = heuristicType( indexBinding.getHibernateTypeDescriptor() ); Type resolvedElementType = heuristicType( indexBinding.getHibernateTypeDescriptor() );
bindHibernateResolvedType( indexBinding.getHibernateTypeDescriptor(), resolvedElementType ); bindHibernateResolvedType( indexBinding.getHibernateTypeDescriptor(), resolvedElementType );
bindJdbcDataType( resolvedElementType, (AbstractValue) indexBinding.getIndexRelationalValue() ); typeHelper.bindJdbcDataType( resolvedElementType, (AbstractValue) indexBinding.getIndexRelationalValue() );
} }
void bindCollectionTableForeignKey( void bindCollectionTableForeignKey(
@ -551,10 +543,10 @@ public class Binder {
if ( resolvedKeyType.isComponentType() ) { if ( resolvedKeyType.isComponentType() ) {
ComponentType componentType = ( ComponentType ) resolvedKeyType; ComponentType componentType = ( ComponentType ) resolvedKeyType;
for ( Type subType : componentType.getSubtypes() ) { for ( Type subType : componentType.getSubtypes() ) {
bindJdbcDataType( subType, fkColumnIterator.next() ); typeHelper.bindJdbcDataType( subType, fkColumnIterator.next() );
} }
} else { } else {
bindJdbcDataType( resolvedKeyType, fkColumnIterator.next() ); typeHelper.bindJdbcDataType( resolvedKeyType, fkColumnIterator.next() );
} }
} }
@ -689,7 +681,7 @@ public class Binder {
hibernateTypeDescriptor.setExplicitTypeName( typeName ); hibernateTypeDescriptor.setExplicitTypeName( typeName );
Type resolvedType = heuristicType( hibernateTypeDescriptor ); Type resolvedType = heuristicType( hibernateTypeDescriptor );
bindHibernateResolvedType( hibernateTypeDescriptor, resolvedType ); bindHibernateResolvedType( hibernateTypeDescriptor, resolvedType );
bindJdbcDataType( resolvedType, value ); typeHelper.bindJdbcDataType( resolvedType, value );
} }
private EntityBinding bindEntities( final EntityHierarchy entityHierarchy ) { private EntityBinding bindEntities( final EntityHierarchy entityHierarchy ) {
@ -884,20 +876,20 @@ public class Binder {
final String defaultJavaTypeName ) { final String defaultJavaTypeName ) {
if ( explicitTypeName == null ) { if ( explicitTypeName == null ) {
if ( hibernateTypeDescriptor.getJavaTypeName() != null ) { if ( hibernateTypeDescriptor.getJavaTypeName() != null ) {
throw new MappingException( String.format( bindingContext().makeMappingException( String.format(
"Attempt to re-initialize (non-explicit) Java type name; current=%s new=%s", "Attempt to re-initialize (non-explicit) Java type name; current=%s new=%s",
hibernateTypeDescriptor.getJavaTypeName(), hibernateTypeDescriptor.getJavaTypeName(),
defaultJavaTypeName ), bindingContexts.peek().getOrigin() ); defaultJavaTypeName ) );
} }
hibernateTypeDescriptor.setJavaTypeName( defaultJavaTypeName ); hibernateTypeDescriptor.setJavaTypeName( defaultJavaTypeName );
} 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)
final TypeDefinition typeDef = metadata.getTypeDefinition( explicitTypeName ); final TypeDefinition typeDef = metadata.getTypeDefinition( explicitTypeName );
if ( hibernateTypeDescriptor.getExplicitTypeName() != null ) { if ( hibernateTypeDescriptor.getExplicitTypeName() != null ) {
throw new MappingException( String.format( bindingContext().makeMappingException( String.format(
"Attempt to re-initialize explicity-mapped Java type name; current=%s new=%s", "Attempt to re-initialize explicity-mapped Java type name; current=%s new=%s",
hibernateTypeDescriptor.getExplicitTypeName(), hibernateTypeDescriptor.getExplicitTypeName(),
explicitTypeName ), bindingContexts.peek().getOrigin() ); explicitTypeName ) );
} }
if ( typeDef == null ) { if ( typeDef == null ) {
hibernateTypeDescriptor.setExplicitTypeName( explicitTypeName ); hibernateTypeDescriptor.setExplicitTypeName( explicitTypeName );
@ -953,14 +945,11 @@ public class Binder {
entityIdentifier.createIdentifierGenerator( identifierGeneratorFactory, properties ); entityIdentifier.createIdentifierGenerator( identifierGeneratorFactory, properties );
if ( IdentityGenerator.class.isInstance( entityIdentifier.getIdentifierGenerator() ) ) { if ( IdentityGenerator.class.isInstance( entityIdentifier.getIdentifierGenerator() ) ) {
if ( rootEntityBinding.getPrimaryTable().getPrimaryKey().getColumnSpan() != 1 ) { if ( rootEntityBinding.getPrimaryTable().getPrimaryKey().getColumnSpan() != 1 ) {
throw new MappingException( bindingContext().makeMappingException( String.format(
String.format(
"ID for %s is mapped as an identity with %d columns. IDs mapped as an identity can only have 1 column.", "ID for %s is mapped as an identity with %d columns. IDs mapped as an identity can only have 1 column.",
rootEntityBinding.getEntity().getName(), rootEntityBinding.getEntity().getName(),
rootEntityBinding.getPrimaryTable().getPrimaryKey().getColumnSpan() rootEntityBinding.getPrimaryTable().getPrimaryKey().getColumnSpan()
), ) );
bindingContexts.peek().getOrigin()
);
} }
rootEntityBinding.getPrimaryTable().getPrimaryKey().getColumns().get( 0 ).setIdentity( true ); rootEntityBinding.getPrimaryTable().getPrimaryKey().getColumns().get( 0 ).setIdentity( true );
} }
@ -986,18 +975,6 @@ public class Binder {
return bindingContexts.peek(); return bindingContexts.peek();
} }
private void bindJdbcDataType( final Type resolvedType, final AbstractValue value ) {
if ( resolvedType != null && value != null ) {
final Type resolvedRelationalType =
resolvedType.isEntityType()
? EntityType.class.cast( resolvedType ).getIdentifierOrUniqueKeyType( metadata )
: resolvedType;
value.setJdbcDataType( new JdbcDataType(
resolvedRelationalType.sqlTypes( metadata )[ 0 ],
resolvedRelationalType.getName(),
resolvedRelationalType.getReturnedClass() ) );
}
}
private AbstractPluralAttributeBinding bindListAttribute( private AbstractPluralAttributeBinding bindListAttribute(
final AttributeBindingContainer attributeBindingContainer, final AttributeBindingContainer attributeBindingContainer,
@ -1021,21 +998,20 @@ public class Binder {
private ManyToOneAttributeBinding bindManyToOneAttribute( private ManyToOneAttributeBinding bindManyToOneAttribute(
final AttributeBindingContainer attributeBindingContainer, final AttributeBindingContainer attributeBindingContainer,
final ToOneAttributeSource attributeSource, final ToOneAttributeSource attributeSource,
SingularAttribute attribute ) { final SingularAttribute singularAttribute ) {
if ( attribute == null ) { final SingularAttribute attribute = singularAttribute != null ? singularAttribute : createSingularAttribute( attributeBindingContainer, attributeSource );
attribute = createSingularAttribute( attributeBindingContainer, attributeSource );
}
// TODO: figure out which table is used (could be secondary table...) // TODO: figure out which table is used (could be secondary table...)
final TableSpecification table = attributeBindingContainer.seekEntityBinding().getPrimaryTable(); final TableSpecification table = attributeBindingContainer.seekEntityBinding().getPrimaryTable();
final List< RelationalValueBinding > relationalValueBindings =
bindValues( attributeBindingContainer, attributeSource, attribute, table );
//find the referenced entitybinding
org.hibernate.internal.util.ValueHolder< Class< ? >> referencedJavaTypeValue = createSingularAttributeJavaType( attribute ); org.hibernate.internal.util.ValueHolder< Class< ? >> referencedJavaTypeValue = createSingularAttributeJavaType( attribute );
final String referencedEntityName = final String referencedEntityName =
bindingContext().qualifyClassName( attributeSource.getReferencedEntityName() != null bindingContext().qualifyClassName( attributeSource.getReferencedEntityName() != null
? attributeSource.getReferencedEntityName() ? attributeSource.getReferencedEntityName()
: referencedJavaTypeValue.getValue().getName() ); : referencedJavaTypeValue.getValue().getName() );
final EntityBinding referencedEntityBinding = entityBinding( referencedEntityName ); final EntityBinding referencedEntityBinding = entityBinding( referencedEntityName );
//now find the referenced attribute binding, either the referenced entity's id attribute or the referenced attribute
//todo referenced entityBinding null check?
// Foreign key... // Foreign key...
final ForeignKeyContributingSource.JoinColumnResolutionDelegate resolutionDelegate = final ForeignKeyContributingSource.JoinColumnResolutionDelegate resolutionDelegate =
attributeSource.getForeignKeyTargetColumnResolutionDelegate(); attributeSource.getForeignKeyTargetColumnResolutionDelegate();
@ -1058,9 +1034,25 @@ public class Binder {
attributeSource.getName(), attributeSource.getName(),
referencedAttributeBinding.getAttribute().getName() ) ); referencedAttributeBinding.getAttribute().getName() ) );
} }
//bind @ManyToOne columns on the owner table
final List< RelationalValueBinding > relationalValueBindings =
bindValues( attributeBindingContainer, attributeSource, attribute, table, new DefaultNamingStrategy(){
@Override
public String defaultName() {
final SingularAttributeBinding referencedSingularAttributeBinding = SingularAttributeBinding.class.cast( referencedAttributeBinding );
final RelationalValueBinding relationalValueBinding = referencedSingularAttributeBinding.getRelationalValueBindings().get( 0 );
final Value referencedValue = relationalValueBinding.getValue();
if(!Column.class.isInstance( referencedValue )){
//todo throw exception?
}
return bindingContext().getNamingStrategy().foreignKeyColumnName( attribute.getName(),
referencedEntityBinding.getEntity().getName(),
referencedEntityBinding.getEntity().getName(),
Column.class.cast( referencedValue ).getColumnName().getText());
}
} );
// todo : currently a chicken-egg problem here between creating the attribute binding and binding its FK values... // todo : currently a chicken-egg problem here between creating the attribute binding and binding its FK values...
// now we have everything to create a ManyToOneAttributeBinding
final ManyToOneAttributeBinding attributeBinding = final ManyToOneAttributeBinding attributeBinding =
attributeBindingContainer.makeManyToOneAttributeBinding( attributeBindingContainer.makeManyToOneAttributeBinding(
attribute, attribute,
@ -1103,7 +1095,7 @@ public class Binder {
attributeSource.getTypeInformation(), attributeSource.getTypeInformation(),
referencedJavaTypeValue ); referencedJavaTypeValue );
bindHibernateResolvedType( attributeBinding.getHibernateTypeDescriptor(), resolvedType ); bindHibernateResolvedType( attributeBinding.getHibernateTypeDescriptor(), resolvedType );
bindJdbcDataType( resolvedType, ( AbstractValue ) relationalValueBindings.get( 0 ).getValue() ); typeHelper.bindJdbcDataType( resolvedType, relationalValueBindings.get( 0 ).getValue() );
attributeBinding.setCascadeStyles( attributeSource.getCascadeStyles() ); attributeBinding.setCascadeStyles( attributeSource.getCascadeStyles() );
attributeBinding.setFetchTiming( attributeSource.getFetchTiming() ); attributeBinding.setFetchTiming( attributeSource.getFetchTiming() );
@ -1318,12 +1310,9 @@ public class Binder {
elementSource.getReferencedEntityName() : elementSource.getReferencedEntityName() :
defaultElementJavaTypeName; defaultElementJavaTypeName;
if ( referencedEntityName == null ) { if ( referencedEntityName == null ) {
throw new MappingException( bindingContext().makeMappingException( String.format( "The mapping for the entity associated with one-to-many attribute (%s) is undefined.",
String.format( "The mapping for the entity associated with one-to-many attribute (%s) is undefined.",
createAttributePath( attributeBinding ) createAttributePath( attributeBinding )
), ) );
bindingContexts.peek().getOrigin()
);
} }
EntityBinding referencedEntityBinding = entityBinding( referencedEntityName ); EntityBinding referencedEntityBinding = entityBinding( referencedEntityName );
bindOneToManyCollectionKey( attributeBinding, attributeSource, referencedEntityBinding ); bindOneToManyCollectionKey( attributeBinding, attributeSource, referencedEntityBinding );
@ -1527,11 +1516,24 @@ public class Binder {
} }
} }
private List<RelationalValueBinding> bindValues(final AttributeBindingContainer attributeBindingContainer,
final RelationalValueSourceContainer valueSourceContainer,
final Attribute attribute,
final TableSpecification defaultTable){
return bindValues( attributeBindingContainer, valueSourceContainer, attribute, defaultTable, new DefaultNamingStrategy() {
@Override
public String defaultName() {
return bindingContexts.peek().getNamingStrategy().propertyToColumnName( attribute.getName() );
}
} );
}
private List< RelationalValueBinding > bindValues( private List< RelationalValueBinding > bindValues(
final AttributeBindingContainer attributeBindingContainer, final AttributeBindingContainer attributeBindingContainer,
final RelationalValueSourceContainer valueSourceContainer, final RelationalValueSourceContainer valueSourceContainer,
final Attribute attribute, final Attribute attribute,
final TableSpecification defaultTable ) { final TableSpecification defaultTable,
final DefaultNamingStrategy defaultNamingStrategy) {
final List< RelationalValueBinding > valueBindings = new ArrayList< RelationalValueBinding >(); final List< RelationalValueBinding > valueBindings = new ArrayList< RelationalValueBinding >();
final SingularAttributeBinding.NaturalIdMutability naturalIdMutability = SingularAttributeSource.class.isInstance( final SingularAttributeBinding.NaturalIdMutability naturalIdMutability = SingularAttributeSource.class.isInstance(
valueSourceContainer valueSourceContainer
@ -1542,7 +1544,7 @@ public class Binder {
if ( valueSourceContainer.relationalValueSources().isEmpty() ) { if ( valueSourceContainer.relationalValueSources().isEmpty() ) {
final String columnName = final String columnName =
quotedIdentifier( bindingContexts.peek().getNamingStrategy().propertyToColumnName( attribute.getName() ) ); quotedIdentifier( defaultNamingStrategy.defaultName() );
final Column column = defaultTable.locateOrCreateColumn( columnName ); final Column column = defaultTable.locateOrCreateColumn( columnName );
column.setNullable( !isNaturalId && valueSourceContainer.areValuesNullableByDefault() ); column.setNullable( !isNaturalId && valueSourceContainer.areValuesNullableByDefault() );
if(isNaturalId){ if(isNaturalId){
@ -1658,9 +1660,7 @@ public class Binder {
final boolean isNullableByDefault, final boolean isNullableByDefault,
final boolean isDefaultAttributeName ) { final boolean isDefaultAttributeName ) {
if ( columnSource.getName() == null && defaultName == null ) { if ( columnSource.getName() == null && defaultName == null ) {
throw new MappingException( bindingContext().makeMappingException( "Cannot resolve name for column because no name was specified and default name is null." );
"Cannot resolve name for column because no name was specified and default name is null.",
bindingContexts.peek().getOrigin() );
} }
final String name; final String name;
if ( StringHelper.isNotEmpty( columnSource.getName() ) ) { if ( StringHelper.isNotEmpty( columnSource.getName() ) ) {
@ -1856,10 +1856,7 @@ public class Binder {
TableSpecification tableSpec = null; TableSpecification tableSpec = null;
if ( tableSpecSource == null ) { if ( tableSpecSource == null ) {
if ( defaultNamingStrategy == null ) { if ( defaultNamingStrategy == null ) {
throw new MappingException( bindingContext().makeMappingException( "An explicit name must be specified for the table" );
"An explicit name must be specified for the table",
bindingContext.getOrigin()
);
} }
String tableName = defaultNamingStrategy.defaultName(); String tableName = defaultNamingStrategy.defaultName();
tableSpec = createTableSpecification( bindingContext, schema, tableName ); tableSpec = createTableSpecification( bindingContext, schema, tableName );
@ -1869,10 +1866,7 @@ public class Binder {
String tableName = tableSource.getExplicitTableName(); String tableName = tableSource.getExplicitTableName();
if ( tableName == null ) { if ( tableName == null ) {
if ( defaultNamingStrategy == null ) { if ( defaultNamingStrategy == null ) {
throw new MappingException( bindingContext().makeMappingException( "An explicit name must be specified for the table" );
"An explicit name must be specified for the table",
bindingContext.getOrigin()
);
} }
tableName = defaultNamingStrategy.defaultName(); tableName = defaultNamingStrategy.defaultName();
} }
@ -2047,12 +2041,12 @@ public class Binder {
referencedAttributeBinding = attributeBinding( entityBinding.getEntity().getName(), referencedAttributeName ); referencedAttributeBinding = attributeBinding( entityBinding.getEntity().getName(), referencedAttributeName );
} }
if ( referencedAttributeBinding == null ) { if ( referencedAttributeBinding == null ) {
throw new MappingException( "Plural attribute key references an attribute binding that does not exist: " bindingContext().makeMappingException( "Plural attribute key references an attribute binding that does not exist: "
+ referencedAttributeBinding, bindingContexts.peek().getOrigin() ); + referencedAttributeBinding );
} }
if ( !referencedAttributeBinding.getAttribute().isSingular() ) { if ( !referencedAttributeBinding.getAttribute().isSingular() ) {
throw new MappingException( "Plural attribute key references a plural attribute; it must not be plural: " bindingContext().makeMappingException( "Plural attribute key references a plural attribute; it must not be plural: "
+ referencedAttributeName, bindingContexts.peek().getOrigin() ); + referencedAttributeName );
} }
return ( SingularAttributeBinding ) referencedAttributeBinding; return ( SingularAttributeBinding ) referencedAttributeBinding;
} }
@ -2078,8 +2072,8 @@ public class Binder {
// Find appropriate source to create binding // Find appropriate source to create binding
final EntitySource entitySource = entitySourcesByName.get( entityName ); final EntitySource entitySource = entitySourcesByName.get( entityName );
if(entitySource == null) { if(entitySource == null) {
String msg = coreLogger.missingEntitySource( entityName ); String msg = log.missingEntitySource( entityName );
throw new MappingException( msg, null ); bindingContext().makeMappingException( msg );
} }
// Get super entity binding (creating it if necessary using recursive call to this method) // Get super entity binding (creating it if necessary using recursive call to this method)

View File

@ -36,6 +36,7 @@ import org.jboss.logging.Logger;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.beans.BeanInfoHelper; 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.MetadataImplementor;
import org.hibernate.metamodel.spi.binding.AttributeBinding; import org.hibernate.metamodel.spi.binding.AttributeBinding;
import org.hibernate.metamodel.spi.binding.BasicAttributeBinding; import org.hibernate.metamodel.spi.binding.BasicAttributeBinding;
@ -79,7 +80,7 @@ import org.hibernate.type.Type;
* Currently the following methods are also required to be non-private because of handling discriminators which * Currently the following methods are also required to be non-private because of handling discriminators which
* are currently not modeled using attributes:<ul> * are currently not modeled using attributes:<ul>
* <li>{@link #determineHibernateTypeFromDescriptor}</li> * <li>{@link #determineHibernateTypeFromDescriptor}</li>
* <li>{@link #pushHibernateTypeInformationDown(org.hibernate.type.Type, org.hibernate.metamodel.spi.relational.Value)}</li> * <li>{@link #bindJdbcDataType(org.hibernate.type.Type, org.hibernate.metamodel.spi.relational.Value)}</li>
* </ul> * </ul>
* *
* @author Steve Ebersole * @author Steve Ebersole
@ -235,7 +236,7 @@ public class HibernateTypeHelper {
return null; return null;
} }
private final Properties EMPTY_PROPERTIES = new Properties(); private static final Properties EMPTY_PROPERTIES = new Properties();
private Type determineHibernateTypeFromAttributeJavaType(SingularAttribute singularAttribute) { private Type determineHibernateTypeFromAttributeJavaType(SingularAttribute singularAttribute) {
if ( singularAttribute.getSingularAttributeType() != null ) { if ( singularAttribute.getSingularAttributeType() != null ) {
@ -254,12 +255,15 @@ public class HibernateTypeHelper {
} }
private static Properties getTypeParameters(HibernateTypeDescriptor hibernateTypeDescriptor) { private static Properties getTypeParameters(HibernateTypeDescriptor hibernateTypeDescriptor) {
Properties typeParameters = new Properties( ); if ( CollectionHelper.isEmpty( hibernateTypeDescriptor.getTypeParameters() ) ) {
if ( hibernateTypeDescriptor.getTypeParameters() != null ) { return EMPTY_PROPERTIES;
typeParameters.putAll( hibernateTypeDescriptor.getTypeParameters() );
} }
else {
Properties typeParameters = new Properties();
typeParameters.putAll( hibernateTypeDescriptor.getTypeParameters() );
return typeParameters; return typeParameters;
} }
}
private void pushHibernateTypeInformationDown( private void pushHibernateTypeInformationDown(
SingularAttributeSource attributeSource, SingularAttributeSource attributeSource,
@ -346,24 +350,27 @@ public class HibernateTypeHelper {
return; return;
} }
final Value value = relationalValueBindings.get( 0 ).getValue(); final Value value = relationalValueBindings.get( 0 ).getValue();
pushHibernateTypeInformationDown( bindJdbcDataType(resolvedHibernateType, value );
(
resolvedHibernateType.isEntityType() ?
( ( EntityType ) resolvedHibernateType ).getIdentifierOrUniqueKeyType( metadata ) :
resolvedHibernateType
),
value
);
} }
public void pushHibernateTypeInformationDown(Type resolvedHibernateType, Value value) { /**
if ( value.getJdbcDataType() == null ) { * Bind relational types using hibernate type just resolved.
*
* @param resolvedHibernateType The hibernate type resolved from metadata.
* @param value The relational value to be binded.
*/
public void bindJdbcDataType(Type resolvedHibernateType, Value value) {
if ( value.getJdbcDataType() == null && resolvedHibernateType != null && value != null ) {
final Type resolvedRelationalType =
resolvedHibernateType.isEntityType()
? EntityType.class.cast( resolvedHibernateType ).getIdentifierOrUniqueKeyType( metadata )
: resolvedHibernateType;
if ( AbstractValue.class.isInstance( value ) ) { if ( AbstractValue.class.isInstance( value ) ) {
( (AbstractValue) value ).setJdbcDataType( ( (AbstractValue) value ).setJdbcDataType(
new JdbcDataType( new JdbcDataType(
resolvedHibernateType.sqlTypes( metadata )[0], resolvedRelationalType.sqlTypes( metadata )[0],
resolvedHibernateType.getName(), resolvedRelationalType.getName(),
resolvedHibernateType.getReturnedClass() resolvedRelationalType.getReturnedClass()
) )
); );
} }

View File

@ -400,7 +400,10 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
if ( profile == null || profile.getName() == null ) { if ( profile == null || profile.getName() == null ) {
throw new IllegalArgumentException( "Fetch profile object or name is null: " + profile ); throw new IllegalArgumentException( "Fetch profile object or name is null: " + profile );
} }
fetchProfiles.put( profile.getName(), profile ); FetchProfile old = fetchProfiles.put( profile.getName(), profile );
if ( old != null ) {
LOG.warn( "Duplicated fetch profile with same name [" + profile.getName() + "] found." );
}
} }
@Override @Override

View File

@ -41,6 +41,7 @@ import org.hibernate.FetchMode;
import org.hibernate.annotations.NotFoundAction; import org.hibernate.annotations.NotFoundAction;
import org.hibernate.engine.FetchStyle; import org.hibernate.engine.FetchStyle;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.PropertyGeneration; import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.internal.source.annotations.attribute.type.AttributeTypeResolver; import org.hibernate.metamodel.internal.source.annotations.attribute.type.AttributeTypeResolver;
import org.hibernate.metamodel.internal.source.annotations.attribute.type.AttributeTypeResolverImpl; import org.hibernate.metamodel.internal.source.annotations.attribute.type.AttributeTypeResolverImpl;
@ -271,7 +272,7 @@ public class AssociationAttribute extends MappedAttribute {
private String determineReferencedEntityType(AnnotationInstance associationAnnotation, Class<?> referencedAttributeType) { private String determineReferencedEntityType(AnnotationInstance associationAnnotation, Class<?> referencedAttributeType) {
// use the annotated attribute type as default target type // use the annotated attribute type as default target type
String targetTypeName = referencedAttributeType.getName(); String targetTypeName = null;
// unless we have an explicit @Target // unless we have an explicit @Target
AnnotationInstance targetAnnotation = JandexHelper.getSingleAnnotation( AnnotationInstance targetAnnotation = JandexHelper.getSingleAnnotation(
@ -287,6 +288,12 @@ public class AssociationAttribute extends MappedAttribute {
targetTypeName = targetEntityValue.asClass().name().toString(); targetTypeName = targetEntityValue.asClass().name().toString();
} }
if( StringHelper.isEmpty( targetTypeName ) && referencedAttributeType!=null ){
targetTypeName = referencedAttributeType.getName();
} else {
getContext().makeMappingException( "Can't find the target type for this collection attribute: "+ getRole() );
}
return targetTypeName; return targetTypeName;
} }

View File

@ -294,6 +294,11 @@ public class ConfiguredClass {
return false; return false;
} }
if ( member instanceof Method && Method.class.cast( member ).getReturnType().equals( void.class ) ){
// not a getter
return false;
}
if ( transientNames.contains( member.getName() ) ) { if ( transientNames.contains( member.getName() ) ) {
return false; return false;
} }
@ -646,6 +651,9 @@ public class ConfiguredClass {
} }
private Class<?> resolveCollectionValuedReferenceType(ResolvedMember resolvedMember) { private Class<?> resolveCollectionValuedReferenceType(ResolvedMember resolvedMember) {
if ( resolvedMember.getType().getTypeParameters().isEmpty() ) {
return null; // no generic at all
}
Class<?> type = resolvedMember.getType().getErasedType(); Class<?> type = resolvedMember.getType().getErasedType();
if ( Collection.class.isAssignableFrom( type ) ) { if ( Collection.class.isAssignableFrom( type ) ) {
return resolvedMember.getType().getTypeParameters().get( 0 ).getErasedType(); return resolvedMember.getType().getTypeParameters().get( 0 ).getErasedType();

View File

@ -228,6 +228,49 @@ public class HibernateMappingProcessor {
private void processFetchProfiles() { private void processFetchProfiles() {
processFetchProfiles( mappingRoot().getFetchProfile(), null ); processFetchProfiles( mappingRoot().getFetchProfile(), null );
for ( JaxbClassElement classElement : mappingRoot().getClazz() ) {
processFetchProfiles(
classElement.getFetchProfile(), mappingDocument.getMappingLocalBindingContext()
.qualifyClassName( classElement.getName() )
);
// processing fetch profiles defined in the <joined-subclass>
processFetchProfilesInJoinedSubclass(classElement.getJoinedSubclass());
// <union-subclass>
processFetchProfilesInUnionSubclass( classElement.getUnionSubclass() );
// <subclass>
processFetchProfilesInSubclass( classElement.getSubclass() );
}
}
private void processFetchProfilesInSubclass(List<JaxbSubclassElement> subclass) {
for ( JaxbSubclassElement subclassElement : subclass ) {
processFetchProfiles(
subclassElement.getFetchProfile(), mappingDocument.getMappingLocalBindingContext()
.qualifyClassName( subclassElement.getName() )
);
processFetchProfilesInSubclass( subclassElement.getSubclass() );
}
}
private void processFetchProfilesInUnionSubclass(List<JaxbUnionSubclassElement> unionSubclass) {
for ( JaxbUnionSubclassElement subclassElement : unionSubclass ) {
processFetchProfiles(
subclassElement.getFetchProfile(), mappingDocument.getMappingLocalBindingContext()
.qualifyClassName( subclassElement.getName() )
);
processFetchProfilesInUnionSubclass( subclassElement.getUnionSubclass() );
}
}
private void processFetchProfilesInJoinedSubclass(List<JaxbJoinedSubclassElement> joinedSubclassElements) {
for ( JaxbJoinedSubclassElement subclassElement : joinedSubclassElements ) {
processFetchProfiles(
subclassElement.getFetchProfile(), mappingDocument.getMappingLocalBindingContext()
.qualifyClassName( subclassElement.getName() )
);
processFetchProfilesInJoinedSubclass( subclassElement.getJoinedSubclass() );
}
} }
public void processFetchProfiles(List<JaxbFetchProfileElement> fetchProfiles, String containingEntityName) { public void processFetchProfiles(List<JaxbFetchProfileElement> fetchProfiles, String containingEntityName) {

View File

@ -32,7 +32,6 @@ import org.hibernate.UnknownProfileException;
import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment; import org.hibernate.cfg.Environment;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -174,7 +173,6 @@ public class JoinFetchProfileTest extends BaseCoreFunctionalTestCase {
} }
@Test @Test
@FailureExpectedWithNewMetamodel
public void testBasicFetchProfileOperation() { public void testBasicFetchProfileOperation() {
assertTrue( "fetch profile not parsed properly", sessionFactory().containsFetchProfileDefinition( "enrollment.details" ) ); assertTrue( "fetch profile not parsed properly", sessionFactory().containsFetchProfileDefinition( "enrollment.details" ) );
assertTrue( "fetch profile not parsed properly", sessionFactory().containsFetchProfileDefinition( "offering.details" ) ); assertTrue( "fetch profile not parsed properly", sessionFactory().containsFetchProfileDefinition( "offering.details" ) );
@ -237,7 +235,6 @@ public class JoinFetchProfileTest extends BaseCoreFunctionalTestCase {
} }
@Test @Test
@FailureExpectedWithNewMetamodel
public void testLoadOneToManyFetchProfile() { public void testLoadOneToManyFetchProfile() {
performWithStandardData( performWithStandardData(
new TestCode() { new TestCode() {
@ -257,7 +254,6 @@ public class JoinFetchProfileTest extends BaseCoreFunctionalTestCase {
} }
@Test @Test
@FailureExpectedWithNewMetamodel
public void testLoadDeepFetchProfile() { public void testLoadDeepFetchProfile() {
performWithStandardData( performWithStandardData(
new TestCode() { new TestCode() {
@ -281,7 +277,6 @@ public class JoinFetchProfileTest extends BaseCoreFunctionalTestCase {
} }
@Test @Test
@FailureExpectedWithNewMetamodel
public void testLoadComponentDerefFetchProfile() { public void testLoadComponentDerefFetchProfile() {
performWithStandardData( performWithStandardData(
new TestCode() { new TestCode() {
@ -306,7 +301,6 @@ public class JoinFetchProfileTest extends BaseCoreFunctionalTestCase {
* TODO : this is actually not strictly true. what we should have happen is to subsequently load those fetches * TODO : this is actually not strictly true. what we should have happen is to subsequently load those fetches
*/ */
@Test @Test
@FailureExpectedWithNewMetamodel
public void testHQL() { public void testHQL() {
performWithStandardData( performWithStandardData(
new TestCode() { new TestCode() {