diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/ObjectNameNormalizer.java b/hibernate-core/src/main/java/org/hibernate/cfg/ObjectNameNormalizer.java index d374505df2..c5f533b250 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/ObjectNameNormalizer.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/ObjectNameNormalizer.java @@ -56,6 +56,10 @@ public abstract class ObjectNameNormalizer { public String handleExplicitName(NamingStrategy strategy, String name); } + public static interface LogicalNamingStrategyHelper extends NamingStrategyHelper{ + public String getLogicalName(NamingStrategy strategy); + } + /** * Performs the actual contract of normalizing a database name. * @@ -78,7 +82,6 @@ public abstract class ObjectNameNormalizer { // handle any quoting for consistent handling in naming strategies objectName = normalizeIdentifierQuoting( explicitName ); objectName = helper.handleExplicitName( getNamingStrategy(), objectName ); - return normalizeIdentifierQuoting( objectName ); } // Conceivable that the naming strategy could return a quoted identifier, or // that user enabled 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 99ab7e02b4..9e18e22468 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 @@ -24,7 +24,7 @@ package org.hibernate.metamodel.internal; import static org.hibernate.engine.spi.SyntheticAttributeHelper.SYNTHETIC_COMPOSITE_ID_ATTRIBUTE_NAME; - +import static org.hibernate.cfg.ObjectNameNormalizer.NamingStrategyHelper; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collections; @@ -99,7 +99,6 @@ import org.hibernate.metamodel.spi.domain.Attribute; 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; import org.hibernate.metamodel.spi.relational.Column; import org.hibernate.metamodel.spi.relational.DerivedValue; import org.hibernate.metamodel.spi.relational.ForeignKey; @@ -462,21 +461,7 @@ public class Binder { } final RelationalValueSource valueSource = discriminatorSource.getDiscriminatorRelationalValueSource(); final TableSpecification table = rootEntityBinding.locateTable( valueSource.getContainingTableName() ); - AbstractValue value; - if ( valueSource.getNature() == RelationalValueSource.Nature.COLUMN ) { - value = - createColumn( - table, - (ColumnSource) valueSource, - bindingContext().getMappingDefaults().getDiscriminatorColumnName(), - false, - false, - false - ); - } - else { - value = table.locateOrCreateDerivedValue( ( (DerivedValueSource) valueSource ).getExpression() ); - } + final Value value = buildDiscriminatorRelationValue( valueSource, table ); final EntityDiscriminator discriminator = new EntityDiscriminator( value, discriminatorSource.isInserted(), discriminatorSource.isForced() ); rootEntityBinding.getHierarchyDetails().setEntityDiscriminator( discriminator ); @@ -488,22 +473,16 @@ public class Binder { bindingContext().locateClassByName( rootEntitySource.getEntityName() ) .getModifiers() ) ) { - // Use the class name as a default if no dscriminator value. + // Use the class name as a default if no discriminator value. // However, skip abstract classes -- obviously no discriminators there. rootEntityBinding.setDiscriminatorMatchValue( rootEntitySource.getEntityName() ); } // Configure discriminator hibernate type - final String typeName = - discriminatorSource.getExplicitHibernateTypeName() != null - ? discriminatorSource.getExplicitHibernateTypeName() - : "string"; - final HibernateTypeDescriptor hibernateTypeDescriptor = discriminator.getExplicitHibernateTypeDescriptor(); - hibernateTypeDescriptor.setExplicitTypeName( typeName ); - Type resolvedType = typeHelper.heuristicType( hibernateTypeDescriptor ); - HibernateTypeHelper.bindHibernateResolvedType( hibernateTypeDescriptor, resolvedType ); - typeHelper.bindJdbcDataType( resolvedType, value ); + typeHelper.bindDiscriminatorType( discriminator, value ); } + + private void bindVersion( final EntityBinding rootEntityBinding, final VersionAttributeSource versionAttributeSource) { @@ -554,7 +533,10 @@ public class Binder { tenantDiscriminatorValue = rootEntityBinding.getPrimaryTable().locateOrCreateColumn( "tenant_id" ); } else { - tenantDiscriminatorValue = buildRelationValue( valueSource, rootEntityBinding.getPrimaryTable() ); + tenantDiscriminatorValue = buildDiscriminatorRelationValue( + valueSource, + rootEntityBinding.getPrimaryTable() + ); } rootEntityBinding.getHierarchyDetails() .getTenantDiscrimination() @@ -596,16 +578,7 @@ public class Binder { includedTable = Table.class.cast( superEntityBinding.getPrimaryTable() ); } table = createTable( - entitySource.getPrimaryTable(), new DefaultNamingStrategy() { - - @Override - public String defaultName() { - String name = StringHelper.isNotEmpty( entityBinding.getJpaEntityName() ) ? entityBinding.getJpaEntityName() : entityBinding - .getEntity().getName(); - return bindingContext().getNamingStrategy().classToTableName( name ); - } - }, - includedTable + entitySource.getPrimaryTable(), new TableNamingStrategyHelper( entityBinding ),includedTable ); tableName = table.getLogicalName().getText(); } @@ -617,9 +590,9 @@ public class Binder { final EntityBinding entityBinding, final EntitySource entitySource) { for ( final SecondaryTableSource secondaryTableSource : entitySource.getSecondaryTables() ) { - final TableSpecification table = createTable( secondaryTableSource.getTableSource(), null ); + final TableSpecification table = createTable( secondaryTableSource.getTableSource(), new TableNamingStrategyHelper( entityBinding ) ); table.addComment( secondaryTableSource.getComment() ); - List joinRelationalValueBindings; + final List joinRelationalValueBindings; // TODO: deal with property-refs??? if ( secondaryTableSource.getPrimaryKeyColumnSources().isEmpty() ) { final List joinedColumns = entityBinding.getPrimaryTable().getPrimaryKey().getColumns(); @@ -672,7 +645,7 @@ public class Binder { // TODO: make the foreign key column the primary key??? final ForeignKey foreignKey = bindForeignKey( - quoteIdentifierIfNonEmpty( secondaryTableSource.getExplicitForeignKeyName() ), + quotedIdentifier( secondaryTableSource.getExplicitForeignKeyName() ), extractColumnsFromRelationalValueBindings( joinRelationalValueBindings ), determineForeignKeyTargetColumns( entityBinding, secondaryTableSource ) ); @@ -806,13 +779,6 @@ public class Binder { createMetaAttributeContext( rootEntityBinding, identifierSource.getMetaAttributeSources() ), idAttributeBindings ); - typeHelper.bindHibernateTypeDescriptor( - syntheticAttributeBinding.getHibernateTypeDescriptor(), - syntheticAttribute.getSingularAttributeType().getClassName(), - null, - null - ); - // Create the synthetic attribute binding. rootEntityBinding.getHierarchyDetails().getEntityIdentifier().prepareAsNonAggregatedCompositeIdentifier( syntheticAttributeBinding, @@ -822,13 +788,7 @@ public class Binder { idClassPropertyAccessorName ); - final Type resolvedType = metadata.getTypeResolver().getTypeFactory().embeddedComponent( - new ComponentMetamodel( syntheticAttributeBinding, true, false ) - ); - HibernateTypeHelper.bindHibernateResolvedType( - syntheticAttributeBinding.getHibernateTypeDescriptor(), - resolvedType - ); + typeHelper.bindNonAggregatedCompositeIdentifierType( syntheticAttributeBinding, syntheticAttribute ); } private void bindIdentifierGenerator(final EntityBinding rootEntityBinding) { @@ -957,7 +917,7 @@ public class Binder { createMetaAttributeContext( attributeBindingContainer, attributeSource ), attributeSource.getGeneration() ); - typeHelper.bindSingularAttributeTypeInformation( + typeHelper.bindSingularAttributeType( attributeSource, attributeBinding ); @@ -1054,21 +1014,18 @@ public class Binder { createMetaAttributeContext( attributeBindingContainer, attributeSource ) ); bindAttributes( attributeBinding, attributeSource ); - Type resolvedType = metadata.getTypeResolver().getTypeFactory().component( - new ComponentMetamodel( attributeBinding, isAttributeIdentifier, false ) + typeHelper.bindAggregatedCompositeAttributeType( + isAttributeIdentifier, + composite, + defaultJavaClassReference, + attributeBinding ); - // TODO: binding the HibernateTypeDescriptor should be simplified since we know the class name already - typeHelper.bindHibernateTypeDescriptor( - attributeBinding.getHibernateTypeDescriptor(), - composite.getClassName(), - null, - defaultJavaClassReference == null ? null : defaultJavaClassReference.getValue().getName() - ); - HibernateTypeHelper.bindHibernateResolvedType( attributeBinding.getHibernateTypeDescriptor(), resolvedType ); return attributeBinding; } + + private ManyToOneAttributeBinding bindManyToOneAttribute( final AttributeBindingContainer attributeBindingContainer, final ToOneAttributeSource attributeSource, @@ -1153,7 +1110,7 @@ public class Binder { ); if ( !hasDerivedValue( attributeBinding.getRelationalValueBindings() ) ) { bindForeignKey( - quoteIdentifierIfNonEmpty( attributeSource.getExplicitForeignKeyName() ), + quotedIdentifier( attributeSource.getExplicitForeignKeyName() ), extractColumnsFromRelationalValueBindings( attributeBinding.getRelationalValueBindings() ), determineForeignKeyTargetColumns( attributeBinding.getReferencedEntityBinding(), @@ -1274,7 +1231,7 @@ public class Binder { ); bindForeignKey( - quoteIdentifierIfNonEmpty( attributeSource.getExplicitForeignKeyName() ), + quotedIdentifier( attributeSource.getExplicitForeignKeyName() ), foreignKeyColumns, determineForeignKeyTargetColumns( attributeBinding.getReferencedEntityBinding(), @@ -1330,9 +1287,9 @@ public class Binder { typeHelper.bindHibernateTypeDescriptor( attributeBinding.getHibernateTypeDescriptor(), attributeSource.getTypeInformation(), - referencedEntityJavaTypeValue + referencedEntityJavaTypeValue.getValue().getName(), + resolvedType ); - HibernateTypeHelper.bindHibernateResolvedType( attributeBinding.getHibernateTypeDescriptor(), resolvedType ); return attributeBinding; } @@ -1382,15 +1339,16 @@ public class Binder { final Type resolvedType = typeHelper.resolvePluralType( attributeBinding, attributeSource, nature ); final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding.getHibernateTypeDescriptor(); - ReflectedCollectionJavaTypes reflectedCollectionJavaTypes = typeHelper.getReflectedCollectionJavaTypes( + ReflectedCollectionJavaTypes reflectedCollectionJavaTypes = HibernateTypeHelper.getReflectedCollectionJavaTypes( attributeBinding ); typeHelper.bindHibernateTypeDescriptor( hibernateTypeDescriptor, attributeSource.getTypeInformation(), - HibernateTypeHelper.defaultCollectionJavaTypeName( reflectedCollectionJavaTypes, attributeSource ) + HibernateTypeHelper.defaultCollectionJavaTypeName( reflectedCollectionJavaTypes, attributeSource ), + resolvedType + ); - HibernateTypeHelper.bindHibernateResolvedType( hibernateTypeDescriptor, resolvedType ); // Note: Collection types do not have a relational model attributeBinding.setFetchTiming( attributeSource.getFetchTiming() ); attributeBinding.setFetchStyle( attributeSource.getFetchStyle() ); @@ -1563,8 +1521,9 @@ public class Binder { ); } attributeBinding.getPluralAttributeKeyBinding().setInverse( false ); - TableSpecification collectionTable = createBasicCollectionTable( - attributeBinding, attributeSource.getCollectionTableSpecificationSource() + TableSpecification collectionTable = createTable( + attributeSource.getCollectionTableSpecificationSource(), + new CollectionTableNamingStrategyHelper( attributeBinding ) ); if ( StringHelper.isNotEmpty( attributeSource.getCollectionTableComment() ) ) { collectionTable.addComment( attributeSource.getCollectionTableComment() ); @@ -1632,9 +1591,9 @@ public class Binder { elementBinding.getHibernateTypeDescriptor(), aggregate.getClassName(), null, - defaultElementJavaClassReference == null ? null : defaultElementJavaClassReference.getValue().getName() + defaultElementJavaClassReference == null ? null : defaultElementJavaClassReference.getValue().getName(), + resolvedType ); - HibernateTypeHelper.bindHibernateResolvedType( elementBinding.getHibernateTypeDescriptor(), resolvedType ); /** * TODO * don't know why, but see org.hibernate.mapping.Property#getCompositeCascadeStyle @@ -1686,9 +1645,7 @@ public class Binder { attributeSource.explicitHibernateTypeSource(), defaultIndexJavaTypeName ); - Type resolvedElementType = typeHelper.heuristicType( indexBinding.getHibernateTypeDescriptor() ); - HibernateTypeHelper.bindHibernateResolvedType( indexBinding.getHibernateTypeDescriptor(), resolvedElementType ); - typeHelper.bindJdbcDataType( resolvedElementType, indexBinding.getIndexRelationalValue() ); + typeHelper.bindJdbcDataType( indexBinding.getHibernateTypeDescriptor().getResolvedTypeMapping(), indexBinding.getIndexRelationalValue() ); } @@ -1717,13 +1674,7 @@ public class Binder { elementBinding.setElementEntityIdentifier( referencedEntityBinding.getHierarchyDetails().getEntityIdentifier() ); - final HibernateTypeDescriptor hibernateTypeDescriptor = elementBinding.getHibernateTypeDescriptor(); - typeHelper.bindHibernateTypeDescriptor( - hibernateTypeDescriptor, - referencedEntityBinding.getEntity().getName(), - null, - defaultElementJavaTypeName - ); + Type resolvedElementType = metadata.getTypeResolver().getTypeFactory().manyToOne( referencedEntityBinding.getEntity().getName(), @@ -1733,8 +1684,12 @@ public class Binder { false, //TODO: should be attributeBinding.isIgnoreNotFound(), false ); - HibernateTypeHelper.bindHibernateResolvedType( - elementBinding.getHibernateTypeDescriptor(), + final HibernateTypeDescriptor hibernateTypeDescriptor = elementBinding.getHibernateTypeDescriptor(); + typeHelper.bindHibernateTypeDescriptor( + hibernateTypeDescriptor, + referencedEntityBinding.getEntity().getName(), + null, + defaultElementJavaTypeName, resolvedElementType ); // no need to bind JDBC data types because element is referenced EntityBinding's ID @@ -1760,35 +1715,18 @@ public class Binder { if ( !elementBinding.getPluralAttributeBinding().getPluralAttributeKeyBinding().isInverse() && !hasDerivedValue( elementBinding.getRelationalValueBindings() ) ) { bindForeignKey( - quoteIdentifierIfNonEmpty( elementSource.getExplicitForeignKeyName() ), + quotedIdentifier( elementSource.getExplicitForeignKeyName() ), extractColumnsFromRelationalValueBindings( elementBinding.getRelationalValueBindings() ), determineForeignKeyTargetColumns( referencedEntityBinding, elementSource ) ); } - final HibernateTypeDescriptor hibernateTypeDescriptor = elementBinding.getHibernateTypeDescriptor(); - typeHelper.bindHibernateTypeDescriptor( - hibernateTypeDescriptor, - referencedEntityBinding.getEntity().getName(), - null, - defaultElementJavaTypeName - ); - final Type resolvedElementType = metadata.getTypeResolver().getTypeFactory().manyToOne( - referencedEntityBinding.getEntity().getName(), - elementSource.getReferencedEntityAttributeName(), - false, - false, - false, //TODO: should be attributeBinding.isIgnoreNotFound(), - false - ); - HibernateTypeHelper.bindHibernateResolvedType( - elementBinding.getHibernateTypeDescriptor(), - resolvedElementType - ); - typeHelper.bindJdbcDataType( - resolvedElementType, - elementBinding.getRelationalValueBindings() + typeHelper.bindManyToManyAttributeType( + elementBinding, + elementSource, + referencedEntityBinding, + defaultElementJavaTypeName ); elementBinding.setCascadeStyle( determineCascadeStyle( elementSource.getCascadeStyles() ) ); elementBinding.setManyToManyWhere( elementSource.getWhere() ); @@ -1797,6 +1735,8 @@ public class Binder { } + + private void bindOneToManyCollectionKey( final AbstractPluralAttributeBinding attributeBinding, final PluralAttributeSource attributeSource, @@ -1871,12 +1811,15 @@ public class Binder { ); } final boolean isInverse = attributeSource.isInverse(); - final TableSpecification collectionTable = createManyToManyCollectionTable( - attributeBinding, - isInverse, - attributeSource.getCollectionTableSpecificationSource(), - referencedEntityBinding - ); + final TableSpecification collectionTable = + createTable( + attributeSource.getCollectionTableSpecificationSource(), + new ManyToManyCollectionTableNamingStrategyHelper( + attributeBinding, + isInverse, + referencedEntityBinding + ) + ); final PluralAttributeKeyBinding keyBinding = attributeBinding.getPluralAttributeKeyBinding(); keyBinding.setInverse( isInverse ); bindCollectionTableForeignKey( attributeBinding, attributeSource.getKeySource(), collectionTable ); @@ -2056,11 +1999,7 @@ public class Binder { for ( RelationalValueBinding relationalValueBinding : singularAttributeBinding .getRelationalValueBindings() ) { if ( Column.class.isInstance( relationalValueBinding.getValue() ) ) { - Identifier columnIdentifier = Identifier.toIdentifier( - quotedIdentifier( - logicalColumnName - ) - ); + Identifier columnIdentifier = createIdentifier( logicalColumnName); Column column = Column.class.cast( relationalValueBinding.getValue() ); if ( column.getColumnName().equals( columnIdentifier ) ) { return column; @@ -2242,7 +2181,7 @@ public class Binder { ); ForeignKey foreignKey = bindForeignKey( - quoteIdentifierIfNonEmpty( keySource.getExplicitForeignKeyName() ), + quotedIdentifier( keySource.getExplicitForeignKeyName() ), sourceColumns, targetColumns ); @@ -2512,6 +2451,9 @@ public class Binder { final String columnName = quotedIdentifier( defaultNamingStrategy.defaultName() ); final Column column = defaultTable.locateOrCreateColumn( columnName ); + + + column.setNullable( !reallyForceNonNullable && valueSourceContainer.areValuesNullableByDefault() ); if ( isNaturalId ) { addUniqueConstraintForNaturalIdColumn( defaultTable, column ); @@ -2536,16 +2478,6 @@ public class Binder { .locateTable( valueSource.getContainingTableName() ); if ( valueSource.getNature() == RelationalValueSource.Nature.COLUMN ) { final ColumnSource columnSource = (ColumnSource) valueSource; - final boolean isIncludedInInsert = - TruthValue.toBoolean( - columnSource.isIncludedInInsert(), - valueSourceContainer.areValuesIncludedInInsertByDefault() - ); - final boolean isIncludedInUpdate = - TruthValue.toBoolean( - columnSource.isIncludedInUpdate(), - valueSourceContainer.areValuesIncludedInUpdateByDefault() - ); Column column = createColumn( table, columnSource, @@ -2557,6 +2489,16 @@ public class Binder { if ( isNaturalId ) { addUniqueConstraintForNaturalIdColumn( table, column ); } + final boolean isIncludedInInsert = + TruthValue.toBoolean( + columnSource.isIncludedInInsert(), + valueSourceContainer.areValuesIncludedInInsertByDefault() + ); + final boolean isIncludedInUpdate = + TruthValue.toBoolean( + columnSource.isIncludedInUpdate(), + valueSourceContainer.areValuesIncludedInUpdateByDefault() + ); valueBindings.add( new RelationalValueBinding( column, @@ -2576,7 +2518,7 @@ public class Binder { } - private Value buildRelationValue( + private Value buildDiscriminatorRelationValue( final RelationalValueSource valueSource, final TableSpecification table) { if ( valueSource.getNature() == RelationalValueSource.Nature.COLUMN ) { @@ -2594,70 +2536,6 @@ public class Binder { } } - - private TableSpecification createBasicCollectionTable( - final AbstractPluralAttributeBinding pluralAttributeBinding, - final TableSpecificationSource tableSpecificationSource) { - final DefaultNamingStrategy defaultNamingStategy = new DefaultNamingStrategy() { - - @Override - public String defaultName() { - final EntityBinding owner = pluralAttributeBinding.getContainer().seekEntityBinding(); - final String ownerTableLogicalName = - Table.class.isInstance( owner.getPrimaryTable() ) - ? ( (Table) owner.getPrimaryTable() ).getPhysicalName().getText() - : null; - return bindingContext().getNamingStrategy().collectionTableName( - owner.getEntity().getName(), - ownerTableLogicalName, - null, - null, - createAttributePath( pluralAttributeBinding ) - ); - } - }; - return createTable( tableSpecificationSource, defaultNamingStategy ); - } - - private TableSpecification createManyToManyCollectionTable( - final AbstractPluralAttributeBinding pluralAttributeBinding, - final boolean isInverse, - final TableSpecificationSource tableSpecificationSource, - final EntityBinding associatedEntityBinding) { - final DefaultNamingStrategy defaultNamingStategy = new DefaultNamingStrategy() { - - @Override - public String defaultName() { - final EntityBinding ownerEntityBinding; - final EntityBinding inverseEntityBinding; - if ( isInverse ) { - ownerEntityBinding = associatedEntityBinding; - inverseEntityBinding = pluralAttributeBinding.getContainer().seekEntityBinding(); - } - else { - ownerEntityBinding = pluralAttributeBinding.getContainer().seekEntityBinding(); - inverseEntityBinding = associatedEntityBinding; - } - final String ownerTableLogicalName = - Table.class.isInstance( ownerEntityBinding.getPrimaryTable() ) - ? ( (Table) ownerEntityBinding.getPrimaryTable() ).getPhysicalName().getText() - : null; - final String inverseTableLogicalName = - Table.class.isInstance( inverseEntityBinding.getPrimaryTable() ) - ? ( (Table) inverseEntityBinding.getPrimaryTable() ).getPhysicalName().getText() - : null; - return bindingContext().getNamingStrategy().collectionTableName( - ownerEntityBinding.getEntity().getName(), - ownerTableLogicalName, - inverseEntityBinding.getEntity().getName(), - inverseTableLogicalName, - createAttributePath( pluralAttributeBinding ) - ); - } - }; - return createTable( tableSpecificationSource, defaultNamingStategy ); - } - private Column createColumn( final TableSpecification table, final ColumnSource columnSource, @@ -2670,8 +2548,10 @@ public class Binder { "Cannot resolve name for column because no name was specified and default name is null." ); } - final String name = resolveColumnName( columnSource, defaultName, isDefaultAttributeName ); - final String resolvedColumnName = quotedIdentifier( name ); + final String resolvedColumnName = nameNormalizer.normalizeDatabaseIdentifier( + columnSource.getName(), + new ColumnNamingStrategyHelper( defaultName, isDefaultAttributeName ) + ); final Column column = table.locateOrCreateColumn( resolvedColumnName ); resolveColumnNullabl( columnSource, forceNotNull, isNullableByDefault, column ); column.setDefaultValue( columnSource.getDefaultValue() ); @@ -2710,87 +2590,59 @@ public class Binder { } } - private String resolveColumnName( - final ColumnSource columnSource, - final String defaultName, - final boolean isDefaultAttributeName) { - final String name; - if ( StringHelper.isNotEmpty( columnSource.getName() ) ) { - name = bindingContext().getNamingStrategy().columnName( columnSource.getName() ); + private TableSpecification createTable( + final TableSpecificationSource tableSpecSource, + final NamingStrategyHelper namingStrategyHelper) { + return createTable( tableSpecSource, namingStrategyHelper, null ); + } + + private TableSpecification createTable( + final TableSpecificationSource tableSpecSource, + final NamingStrategyHelper namingStrategyHelper, + final Table includedTable) { + if ( tableSpecSource == null && namingStrategyHelper == null ) { + throw bindingContext().makeMappingException( "An explicit name must be specified for the table" ); } - else if ( isDefaultAttributeName ) { - name = bindingContext().getNamingStrategy().propertyToColumnName( defaultName ); + final boolean isTableSourceNull = tableSpecSource == null; + final Schema schema = resolveSchema( tableSpecSource ); + + TableSpecification tableSpec; + if ( isTableSourceNull || tableSpecSource instanceof TableSource ) { + String explicitName = isTableSourceNull ? null : TableSource.class.cast( tableSpecSource ).getExplicitTableName(); + String tableName = nameNormalizer.normalizeDatabaseIdentifier( explicitName, namingStrategyHelper ); + String logicTableName = TableNamingStrategyHelper.class.cast( namingStrategyHelper ).getLogicalName( bindingContext().getNamingStrategy()); + tableSpec = createTableSpecification( schema, tableName, logicTableName, includedTable ); } else { - name = bindingContext().getNamingStrategy().columnName( defaultName ); + final InLineViewSource inLineViewSource = (InLineViewSource) tableSpecSource; + tableSpec = schema.createInLineView( + createIdentifier( inLineViewSource.getLogicalName() ), + inLineViewSource.getSelectStatement() + ); } - return name; + return tableSpec; } - - private TableSpecification createTable( - final TableSpecificationSource tableSpecSource, - final DefaultNamingStrategy defaultNamingStrategy) { - return createTable( tableSpecSource, defaultNamingStrategy, null ); - - } - - private TableSpecification createTable( - final TableSpecificationSource tableSpecSource, - final DefaultNamingStrategy defaultNamingStrategy, - final Table includedTable) { - - final LocalBindingContext bindingContext = bindingContext(); - final MappingDefaults mappingDefaults = bindingContext.getMappingDefaults(); - final boolean isTableSourceNull = tableSpecSource == null; - final String explicitCatalogName = isTableSourceNull ? null : tableSpecSource.getExplicitCatalogName(); - final String explicitSchemaName = isTableSourceNull ? null : tableSpecSource.getExplicitSchemaName(); + private Schema resolveSchema(final TableSpecificationSource tableSpecSource) { + final boolean tableSourceNull = tableSpecSource == null; + final MappingDefaults mappingDefaults = bindingContext().getMappingDefaults(); + final String explicitCatalogName = tableSourceNull ? null : tableSpecSource.getExplicitCatalogName(); + final String explicitSchemaName = tableSourceNull ? null : tableSpecSource.getExplicitSchemaName(); final Schema.Name schemaName = new Schema.Name( createIdentifier( explicitCatalogName, mappingDefaults.getCatalogName() ), createIdentifier( explicitSchemaName, mappingDefaults.getSchemaName() ) ); - final Schema schema = bindingContext.getMetadataImplementor().getDatabase().locateSchema( schemaName ); - - TableSpecification tableSpec; - if ( isTableSourceNull ) { - if ( defaultNamingStrategy == null ) { - throw bindingContext().makeMappingException( "An explicit name must be specified for the table" ); - } - String tableName = defaultNamingStrategy.defaultName(); - tableSpec = createTableSpecification( bindingContext, schema, tableName, includedTable ); - } - else if ( tableSpecSource instanceof TableSource ) { - final TableSource tableSource = (TableSource) tableSpecSource; - String tableName = tableSource.getExplicitTableName(); - if ( tableName == null ) { - if ( defaultNamingStrategy == null ) { - throw bindingContext().makeMappingException( "An explicit name must be specified for the table" ); - } - tableName = defaultNamingStrategy.defaultName(); - } - tableSpec = createTableSpecification( bindingContext, schema, tableName, includedTable ); - } - else { - final InLineViewSource inLineViewSource = (InLineViewSource) tableSpecSource; - tableSpec = schema.createInLineView( - Identifier.toIdentifier( inLineViewSource.getLogicalName() ), - inLineViewSource.getSelectStatement() - ); - } - - return tableSpec; + return metadata.getDatabase().locateSchema( schemaName ); } private TableSpecification createTableSpecification( - final LocalBindingContext bindingContext, final Schema schema, final String tableName, + final String logicTableName, final Table includedTable) { - String name = quotedIdentifier( tableName ); - final Identifier logicalTableId = Identifier.toIdentifier( name ); - name = quotedIdentifier( bindingContext.getNamingStrategy().tableName( name ) ); - final Identifier physicalTableId = Identifier.toIdentifier( name ); + final Identifier logicalTableId = createIdentifier( logicTableName ); + final Identifier physicalTableId = createIdentifier( tableName ); final Table table = schema.locateTable( logicalTableId ); if ( table != null ) { return table; @@ -2981,17 +2833,16 @@ public class Binder { : propertyAccessorName; } - private String quoteIdentifierIfNonEmpty(final String name) { - return StringHelper.isEmpty( name ) ? null : quotedIdentifier( name ); + private String quotedIdentifier(final String name) { + return nameNormalizer.normalizeIdentifierQuoting( name ); } - private String quotedIdentifier(final String name) { - return bindingContext().isGloballyQuotedIdentifiers() ? StringHelper.quote( name ) : name; + private Identifier createIdentifier(final String name){ + return createIdentifier( name, null ); } private Identifier createIdentifier(final String name, final String defaultName) { String identifier = StringHelper.isEmpty( name ) ? defaultName : name; - identifier = quotedIdentifier( identifier ); return Identifier.toIdentifier( identifier ); } @@ -3199,12 +3050,9 @@ public class Binder { return false; } - private static String createAttributePath( + static String createAttributePath( final AttributeBinding attributeBinding) { - return new StringBuffer( attributeBinding.getContainer().getPathBase() ) - .append( '.' ) - .append( attributeBinding.getAttribute().getName() ) - .toString(); + return attributeBinding.getContainer().getPathBase() + '.' + attributeBinding.getAttribute().getName(); } @@ -3324,7 +3172,7 @@ public class Binder { String logicalTableName, String logicalSchemaName, String logicalCatalogName) { - Identifier tableIdentifier = Identifier.toIdentifier( logicalTableName ); + Identifier tableIdentifier = createIdentifier( logicalTableName ); if ( tableIdentifier == null ) { tableIdentifier = referencedEntityBinding.getPrimaryTable().getLogicalName(); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/CollectionTableNamingStrategyHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/CollectionTableNamingStrategyHelper.java new file mode 100644 index 0000000000..f5f6013178 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/CollectionTableNamingStrategyHelper.java @@ -0,0 +1,69 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2012, 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; + +import org.hibernate.cfg.NamingStrategy; +import org.hibernate.metamodel.spi.binding.AbstractPluralAttributeBinding; +import org.hibernate.metamodel.spi.relational.Table; + +/** + * @author Strong Liu + */ +public class CollectionTableNamingStrategyHelper extends TableNamingStrategyHelper { + private final String ownerTableLogicalName; + private final String propertyName; + + public CollectionTableNamingStrategyHelper(final AbstractPluralAttributeBinding pluralAttributeBinding) { + super( pluralAttributeBinding.getContainer().seekEntityBinding() ); + this.ownerTableLogicalName = + Table.class.isInstance( entityBinding.getPrimaryTable() ) + ? ( (Table) entityBinding.getPrimaryTable() ).getPhysicalName().getText() + : null; + this.propertyName = Binder.createAttributePath( pluralAttributeBinding ); + } + + @Override + public String determineImplicitName(NamingStrategy strategy) { + + + return strategy.collectionTableName( + entityBinding.getEntity().getName(), + ownerTableLogicalName, + null, + null, + propertyName + + ); + } + + @Override + public String getLogicalName(NamingStrategy strategy) { + return strategy.logicalCollectionTableName( + logicalName, + ownerTableLogicalName, + null, + propertyName + ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/ColumnNamingStrategyHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/ColumnNamingStrategyHelper.java new file mode 100644 index 0000000000..c077d78dda --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/ColumnNamingStrategyHelper.java @@ -0,0 +1,57 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2012, 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; + +import org.hibernate.cfg.NamingStrategy; +import org.hibernate.cfg.ObjectNameNormalizer; + +/** + * @author Strong Liu + */ +public class ColumnNamingStrategyHelper implements ObjectNameNormalizer.NamingStrategyHelper { + private final String defaultName; + private final boolean isDefaultAttributeName; + + public ColumnNamingStrategyHelper( + final String defaultName, + final boolean isDefaultAttributeName) { + this.defaultName = defaultName; + this.isDefaultAttributeName = isDefaultAttributeName; + } + + @Override + public String determineImplicitName(NamingStrategy strategy) { + if ( isDefaultAttributeName ) { + return strategy.propertyToColumnName( defaultName ); + } + else { + return strategy.columnName( defaultName ); + } + } + + @Override + public String handleExplicitName(NamingStrategy strategy, String name) { + return strategy.columnName( name ); + } +} 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 b16a4e0e57..d4aa48512b 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 @@ -43,13 +43,16 @@ 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.EntityDiscriminator; import org.hibernate.metamodel.spi.binding.EntityIdentifier; import org.hibernate.metamodel.spi.binding.HibernateTypeDescriptor; +import org.hibernate.metamodel.spi.binding.ManyToManyPluralAttributeElementBinding; import org.hibernate.metamodel.spi.binding.PluralAttributeBinding; -import org.hibernate.metamodel.spi.binding.PluralAttributeElementBinding; 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.Aggregate; import org.hibernate.metamodel.spi.domain.PluralAttribute; import org.hibernate.metamodel.spi.domain.SingularAttribute; import org.hibernate.metamodel.spi.relational.AbstractValue; @@ -59,9 +62,10 @@ import org.hibernate.metamodel.spi.source.AttributeSource; import org.hibernate.metamodel.spi.source.BasicPluralAttributeElementSource; import org.hibernate.metamodel.spi.source.ComponentAttributeSource; import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource; +import org.hibernate.metamodel.spi.source.ManyToManyPluralAttributeElementSource; import org.hibernate.metamodel.spi.source.PluralAttributeSource; import org.hibernate.metamodel.spi.source.SingularAttributeSource; -import org.hibernate.type.ComponentType; +import org.hibernate.tuple.component.ComponentMetamodel; import org.hibernate.type.CompositeType; import org.hibernate.type.EntityType; import org.hibernate.type.Type; @@ -85,7 +89,7 @@ import org.jboss.logging.Logger; * *

* Methods intended as entry points are:

    - *
  • {@link #bindSingularAttributeTypeInformation}
  • + *
  • {@link #bindSingularAttributeType}
  • *
*

* Currently the following methods are also required to be non-private because of handling discriminators which @@ -100,7 +104,16 @@ import org.jboss.logging.Logger; class HibernateTypeHelper { private static final Logger log = Logger.getLogger( HibernateTypeHelper.class ); - /* package-protected */ + /** + * package-protected + *

+ * Model a plural attribute's type info, including : + *

    + *
  • collection type, like {@code list}, {@code set} etc
  • + *
  • elements' type, which belongs in this collection
  • + *
  • collection index type
  • + *
+ */ static class ReflectedCollectionJavaTypes { private final String collectionTypeName; private final String collectionElementTypeName; @@ -146,19 +159,107 @@ class HibernateTypeHelper { .reportedJavaType() .getName(); } - - static void bindHibernateResolvedType( - final HibernateTypeDescriptor hibernateTypeDescriptor, - final Type resolvedType) { - // 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() ); - } - hibernateTypeDescriptor.setToOne( resolvedType.isEntityType() ); - } + static ReflectedCollectionJavaTypes getReflectedCollectionJavaTypes( + final PluralAttributeBinding attributeBinding) { + return determineJavaType( attributeBinding.getAttribute() ); } + //-------------------------------------------------------------------------------- + + /** + * Bind type info into {@link HibernateTypeDescriptor}. The strategy below applied: + *

+ *

    + *
  • if {@param resolvedType} is not null, then we can get resolvedTypeMapping, javaTypeName, toOne from it.
  • + *
  • Or, we have to use provided {@param explicitTypeName} / {@param defaultJavaTypeName} to resolve hibernate type
  • + *
+ * + * @param hibernateTypeDescriptor + * The target {@link HibernateTypeDescriptor} to be bind. Can not be null. + * + * @param explicitTypeName + * + * Explicit type name defined in the mapping or resolved from referenced attribute. + * null is accepted. + * + * @param explictTypeParameters + * + * Explicit type parameters defined in the mapping or resolved from refrenced attribute type. + * null is accepted. + * + * @param defaultJavaTypeName + * + * Attribute java type. null is accepted. + * + * @param resolvedType + * + * Provided hibernate type. null is accepted. + */ + void bindHibernateTypeDescriptor( + final HibernateTypeDescriptor hibernateTypeDescriptor, + final String explicitTypeName, + final Map explictTypeParameters, + final String defaultJavaTypeName, + final Type resolvedType) { + Type type; + if ( resolvedType != null ) { + type = resolvedType; + } + else { + //1. pre processing, resolve either explicitType or javaType + preProcessHibernateTypeDescriptor( + hibernateTypeDescriptor, + explicitTypeName, + explictTypeParameters, + defaultJavaTypeName + ); + //2. resolve hibernate type + type = heuristicType( hibernateTypeDescriptor ); + } + if ( type == null ) { + //todo how to deal with this? + } + //3. now set hibernateTypeDescripter's ResolvedTypeMapping and defaultJavaType (if not yet) + hibernateTypeDescriptor.setResolvedTypeMapping( type ); + } + + void bindHibernateTypeDescriptor( + final HibernateTypeDescriptor hibernateTypeDescriptor, + final String explicitTypeName, + final Map explictTypeParameters, + final String defaultJavaTypeName) { + bindHibernateTypeDescriptor( + hibernateTypeDescriptor, + explicitTypeName, + explictTypeParameters, + defaultJavaTypeName, + null + ); + } + + + void bindHibernateTypeDescriptor( + final HibernateTypeDescriptor hibernateTypeDescriptor, + final ExplicitHibernateTypeSource explicitTypeSource, + final String defaultJavaTypeName){ + bindHibernateTypeDescriptor( hibernateTypeDescriptor, explicitTypeSource, defaultJavaTypeName, null); + } + + void bindHibernateTypeDescriptor( + final HibernateTypeDescriptor hibernateTypeDescriptor, + final ExplicitHibernateTypeSource explicitTypeSource, + final String defaultJavaTypeName, + final Type resolvedType) { + final String explicitTypeName = explicitTypeSource != null ? explicitTypeSource.getName() : null; + final Map parameters = explicitTypeSource != null ? explicitTypeSource.getParameters() : null; + bindHibernateTypeDescriptor( + hibernateTypeDescriptor, + explicitTypeName, + parameters, + defaultJavaTypeName, + resolvedType + ); + } + //-------------------------------------------------------------------------------- private final Binder binder; private final MetadataImplementor metadata; @@ -179,7 +280,7 @@ class HibernateTypeHelper { void bindJdbcDataType( final Type resolvedHibernateType, final Value value) { - if ( value.getJdbcDataType() == null && resolvedHibernateType != null && value != null ) { + if ( value != null && value.getJdbcDataType() == null && resolvedHibernateType != null ) { final Type resolvedRelationalType = resolvedHibernateType.isEntityType() ? EntityType.class.cast( resolvedHibernateType ).getIdentifierOrUniqueKeyType( metadata ) @@ -217,6 +318,23 @@ class HibernateTypeHelper { } } + void bindAggregatedCompositeAttributeType( + final boolean isAttributeIdentifier, + final Aggregate composite, + final ValueHolder> defaultJavaClassReference, + final CompositeAttributeBinding attributeBinding) { + Type resolvedType = typeFactory().component( + new ComponentMetamodel( attributeBinding, isAttributeIdentifier, false ) + ); + bindHibernateTypeDescriptor( + attributeBinding.getHibernateTypeDescriptor(), + composite.getClassName(), + null, + defaultJavaClassReference == null ? null : defaultJavaClassReference.getValue().getName(), + resolvedType + ); + } + void bindBasicCollectionElementType( final BasicPluralAttributeElementBinding elementBinding, final BasicPluralAttributeElementSource elementSource, @@ -226,14 +344,96 @@ class HibernateTypeHelper { elementSource.getExplicitHibernateTypeSource(), defaultElementJavaTypeName ); - Type resolvedElementType = heuristicType( elementBinding.getHibernateTypeDescriptor() ); - bindHibernateResolvedType( elementBinding.getHibernateTypeDescriptor(), resolvedElementType ); + bindJdbcDataType( + elementBinding.getHibernateTypeDescriptor().getResolvedTypeMapping(), + elementBinding.getRelationalValueBindings() + ); + } + void bindNonAggregatedCompositeIdentifierType( + final CompositeAttributeBinding syntheticAttributeBinding, + final SingularAttribute syntheticAttribute) { + final Type resolvedType = typeFactory().embeddedComponent( + new ComponentMetamodel( syntheticAttributeBinding, true, false ) + ); + final HibernateTypeDescriptor typeDescriptor = syntheticAttributeBinding.getHibernateTypeDescriptor(); + bindHibernateTypeDescriptor( + typeDescriptor, + syntheticAttribute.getSingularAttributeType().getClassName(), + null, + null, + resolvedType + ); + } + void bindManyToManyAttributeType( + final ManyToManyPluralAttributeElementBinding elementBinding, + final ManyToManyPluralAttributeElementSource elementSource, + final EntityBinding referencedEntityBinding, + final String defaultElementJavaTypeName) { + final Type resolvedElementType = typeFactory().manyToOne( + referencedEntityBinding.getEntity().getName(), + elementSource.getReferencedEntityAttributeName(), + false, + false, + false, //TODO: should be attributeBinding.isIgnoreNotFound(), + false + ); + final HibernateTypeDescriptor hibernateTypeDescriptor = elementBinding.getHibernateTypeDescriptor(); + bindHibernateTypeDescriptor( + hibernateTypeDescriptor, + referencedEntityBinding.getEntity().getName(), + null, + defaultElementJavaTypeName, + resolvedElementType + ); bindJdbcDataType( resolvedElementType, elementBinding.getRelationalValueBindings() ); } + void bindDiscriminatorType(EntityDiscriminator discriminator, Value value) { + bindHibernateTypeDescriptor( + discriminator.getExplicitHibernateTypeDescriptor(), + null, + null, + String.class.getName() + ); + bindJdbcDataType( discriminator.getExplicitHibernateTypeDescriptor().getResolvedTypeMapping(), value ); + } + + void bindSingularAttributeType( + final SingularAttributeSource attributeSource, + final SingularAttributeBinding attributeBinding) { + final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding + .getHibernateTypeDescriptor(); + final Class attributeJavaType = determineJavaType( attributeBinding); + //try to resolve this attribute's java type first + final String defaultJavaTypeName; + if ( attributeJavaType != null ) { + attributeBinding.getAttribute().resolveType( + makeJavaType( + attributeJavaType.getName() + ) + ); + defaultJavaTypeName = attributeJavaType.getName(); + } else { + defaultJavaTypeName = null; + } + //do our best to full fill hibernateTypeDescriptor + bindHibernateTypeDescriptor( + hibernateTypeDescriptor, + attributeSource.getTypeInformation(), + defaultJavaTypeName + ); + + processSingularAttributeTypeInformation( + attributeSource, + attributeBinding + ); + } + + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ hibernate type resolver Type resolvePluralType( final PluralAttributeBinding pluralAttributeBinding, final PluralAttributeSource pluralAttributeSource, @@ -242,48 +442,42 @@ class HibernateTypeHelper { return resolveCustomCollectionType( pluralAttributeBinding ); } else { - final TypeFactory typeFactory = metadata.getTypeResolver().getTypeFactory(); final String role = pluralAttributeBinding.getAttribute().getRole(); final String propertyRef = getReferencedPropertyNameIfNotId( pluralAttributeBinding ); - final boolean embedded = pluralAttributeBinding.getPluralAttributeElementBinding() - .getNature() == PluralAttributeElementBinding.Nature.AGGREGATE; switch ( nature ) { case BAG: - return typeFactory.bag( role, propertyRef, embedded ); + return typeFactory().bag( role, propertyRef ); case LIST: - return typeFactory.list( role, propertyRef, embedded ); + return typeFactory().list( role, propertyRef ); case ARRAY: - return typeFactory.array( + return typeFactory().array( role, propertyRef, - embedded, pluralAttributeSource.getElementClassReference().getValue() ); case MAP: if ( pluralAttributeBinding.isSorted() ) { - return typeFactory.sortedMap( + return typeFactory().sortedMap( role, propertyRef, - embedded, pluralAttributeBinding.getComparator() ); } // TODO: else if ( pluralAttributeBinding.hasOrder() ) { orderedMap... } else { - return typeFactory.map( role, propertyRef, embedded ); + return typeFactory().map( role, propertyRef ); } case SET: if ( pluralAttributeBinding.isSorted() ) { - return typeFactory.sortedSet( + return typeFactory().sortedSet( role, propertyRef, - embedded, pluralAttributeBinding.getComparator() ); } // TODO: else if ( pluralAttributeBinding.hasOrder() ) { orderedSet... } else { - return typeFactory.set( role, propertyRef, embedded ); + return typeFactory().set( role, propertyRef ); } default: throw new NotYetImplementedException( nature + " is to be implemented" ); @@ -291,60 +485,100 @@ class HibernateTypeHelper { } } - Type heuristicType( - final 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 TypeFactory typeFactory(){ + return metadata.getTypeResolver().getTypeFactory(); } - // TODO: The following 3 methods should eventually be replaced w/ - // typeHelper use. - void bindHibernateTypeDescriptor( - final HibernateTypeDescriptor hibernateTypeDescriptor, - final ExplicitHibernateTypeSource explicitTypeSource, - final ValueHolder> defaultJavaType) { - // if there is an explicit type name specified, then there's no reason to - // initialize the default Java type name; simply pass a null default instead. - bindHibernateTypeDescriptor( - hibernateTypeDescriptor, - explicitTypeSource, - explicitTypeSource == null || explicitTypeSource.getName() == null - ? defaultJavaType.getValue().getName() - : null + private Type determineHibernateTypeFromAttributeJavaType( + final SingularAttribute singularAttribute) { + if ( singularAttribute.getSingularAttributeType() != null ) { + return getHeuristicType( + singularAttribute.getSingularAttributeType().getClassName(), + null + ); + } + return null; + } + private Type resolveCustomCollectionType( + final PluralAttributeBinding pluralAttributeBinding) { + final HibernateTypeDescriptor hibernateTypeDescriptor = pluralAttributeBinding.getHibernateTypeDescriptor(); + Properties typeParameters = getTypeParameters( hibernateTypeDescriptor ); + return typeFactory().customCollection( + hibernateTypeDescriptor.getExplicitTypeName(), + typeParameters, + pluralAttributeBinding.getAttribute().getName(), + getReferencedPropertyNameIfNotId( pluralAttributeBinding ) ); } - - void bindHibernateTypeDescriptor( - final HibernateTypeDescriptor hibernateTypeDescriptor, - final ExplicitHibernateTypeSource explicitTypeSource, - final String defaultJavaTypeName) { - if ( explicitTypeSource == null ) { - bindHibernateTypeDescriptor( - hibernateTypeDescriptor, null, null, defaultJavaTypeName - ); + /** + * Resolve hibernate type with info from {@link HibernateTypeDescriptor} using {@link org.hibernate.type.TypeResolver}. + *

+ * return null if can't resolve. + */ + private Type heuristicType( + final HibernateTypeDescriptor hibernateTypeDescriptor) { + if ( hibernateTypeDescriptor.getResolvedTypeMapping() != null ) { + return hibernateTypeDescriptor.getResolvedTypeMapping(); } - else { - bindHibernateTypeDescriptor( - hibernateTypeDescriptor, - explicitTypeSource.getName(), - explicitTypeSource.getParameters(), - defaultJavaTypeName - ); + String typeName = determineTypeName( hibernateTypeDescriptor ); + Properties typeParameters = getTypeParameters( hibernateTypeDescriptor ); + Type type = getHeuristicType( typeName, typeParameters ); + hibernateTypeDescriptor.setResolvedTypeMapping( type ); + return type; + } + + private Type getHeuristicType( + final String typeName, + final Properties typeParameters) { + if ( typeName != null ) { + try { + return metadata.getTypeResolver().heuristicType( typeName, typeParameters ); + } + catch ( Exception ignore ) { + } + } + + return null; + } + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ private scope methods + + /** + * Given an attribute, process all of its type information. This includes resolving the actual + * {@link Type} instance and pushing JDBC/java information from that type down. + * + * @param attributeSource The attribute source. + * @param attributeBinding The attribute. + */ + private void processSingularAttributeTypeInformation( + final SingularAttributeSource attributeSource, + final SingularAttributeBinding attributeBinding) { + Type resolvedType = attributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping(); + + if ( resolvedType == null ) { + // we can determine the Hibernate Type if either: + // 1) the user explicitly named a Type in a HibernateTypeDescriptor + // 2) we know the java type of the attribute + resolvedType = heuristicType( attributeBinding.getHibernateTypeDescriptor() ); + if ( resolvedType == null ) { + resolvedType = determineHibernateTypeFromAttributeJavaType( attributeBinding.getAttribute() ); + } + } + + if ( resolvedType != null ) { + pushHibernateTypeInformationDown( attributeSource, attributeBinding, resolvedType ); + } else{ + //todo throw exception?? } } - void bindHibernateTypeDescriptor( + private void preProcessHibernateTypeDescriptor( final HibernateTypeDescriptor hibernateTypeDescriptor, final String explicitTypeName, final Map explictTypeParameters, final String defaultJavaTypeName) { if ( explicitTypeName == null ) { - if ( hibernateTypeDescriptor.getJavaTypeName() != null ) { + if ( defaultJavaTypeName != null && hibernateTypeDescriptor.getJavaTypeName() != null ) { throw binder.bindingContext().makeMappingException( String.format( "Attempt to re-initialize (non-explicit) Java type name; current=%s new=%s", @@ -381,193 +615,17 @@ class HibernateTypeHelper { } } - void bindSingularAttributeTypeInformation( - final SingularAttributeSource attributeSource, - final SingularAttributeBinding attributeBinding) { - final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding - .getHibernateTypeDescriptor(); - - final Class attributeJavaType = attributeBinding.getContainer() - .seekEntityBinding() - .getHierarchyDetails() - .getEntityMode() == EntityMode.POJO ? determineJavaType( - attributeBinding.getAttribute() - ) : null; - if ( attributeJavaType != null ) { - attributeBinding.getAttribute().resolveType( - makeJavaType( - attributeJavaType.getName() - ) - ); - if ( hibernateTypeDescriptor.getJavaTypeName() == null ) { - hibernateTypeDescriptor.setJavaTypeName( - attributeJavaType.getName() - ); - } - } - - bindHibernateTypeInformation( - attributeSource.getTypeInformation(), - hibernateTypeDescriptor - ); - - processSingularAttributeTypeInformation( - attributeSource, - attributeBinding - ); - } - - ReflectedCollectionJavaTypes getReflectedCollectionJavaTypes( - final PluralAttributeBinding attributeBinding) { - return determineJavaType( attributeBinding.getAttribute() ); - } - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ private scope methods - private Class determineJavaType(final SingularAttribute attribute) { - try { - final Class ownerClass = attribute.getAttributeContainer().getClassReference(); - return ReflectHelper.reflectedPropertyClass( ownerClass, attribute.getName() ); - } - catch ( Exception ignore ) { - log.debugf( - "Unable to locate attribute [%s] on class [%s]", - attribute.getName(), - attribute.getAttributeContainer().getClassName() - ); - } - return null; - } - - private ReflectedCollectionJavaTypes determineJavaType(PluralAttribute attribute) { - try { - final Class ownerClass = attribute.getAttributeContainer().getClassReference(); - PluralAttributeJavaTypeDeterminerDelegate delegate = new PluralAttributeJavaTypeDeterminerDelegate( - ownerClass, - attribute.getName() - ); - BeanInfoHelper.visitBeanInfo( ownerClass, delegate ); - return delegate.collectionJavaTypes; - } - catch ( Exception ignore ) { - log.debugf( - "Unable to locate attribute [%s] on class [%s]", - attribute.getName(), - attribute.getAttributeContainer().getClassName() - ); - } - return null; - } - - /** - * Takes explicit source type information and applies it to the binding model. - * - * @param typeSource The source (user supplied) hibernate type information - * @param hibernateTypeDescriptor The binding model hibernate type information - */ - private void bindHibernateTypeInformation( - final ExplicitHibernateTypeSource typeSource, - final HibernateTypeDescriptor hibernateTypeDescriptor) { - - final String explicitTypeName = typeSource.getName(); - - if ( explicitTypeName != null ) { - final TypeDefinition typeDefinition = metadata.getTypeDefinition( - explicitTypeName - ); - if ( typeDefinition != null ) { - 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 ) { - // Don't use set() -- typeDef#parameters is unmodifiable - hibernateTypeDescriptor.getTypeParameters().putAll( - parameters - ); - } - } - } - - /** - * Given an attribute, process all of its type information. This includes resolving the actual - * {@link Type} instance and pushing JDBC/java information from that type down. - * - * @param attributeSource The attribute source. - * @param attributeBinding The attribute. - */ - private void processSingularAttributeTypeInformation( - final SingularAttributeSource attributeSource, - final SingularAttributeBinding attributeBinding) { - Type resolvedType = attributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping(); - - if ( resolvedType == null ) { - // we can determine the Hibernate Type if either: - // 1) the user explicitly named a Type in a HibernateTypeDescriptor - // 2) we know the java type of the attribute - resolvedType = determineHibernateTypeFromDescriptor( attributeBinding.getHibernateTypeDescriptor() ); - if ( resolvedType == null ) { - resolvedType = determineHibernateTypeFromAttributeJavaType( attributeBinding.getAttribute() ); - } - } - - if ( resolvedType != null ) { - pushHibernateTypeInformationDown( attributeSource, attributeBinding, resolvedType ); - } - } - - private Type determineHibernateTypeFromDescriptor( - final HibernateTypeDescriptor hibernateTypeDescriptor) { - if ( hibernateTypeDescriptor.getResolvedTypeMapping() != null ) { - return hibernateTypeDescriptor.getResolvedTypeMapping(); - } - String typeName = determineTypeName( hibernateTypeDescriptor ); - Properties typeParameters = getTypeParameters( hibernateTypeDescriptor ); - Type type = getHeuristicType( typeName, typeParameters ); - hibernateTypeDescriptor.setResolvedTypeMapping( type ); - return type; - } - - private Type getHeuristicType( - final String typeName, - final Properties typeParameters) { - if ( typeName != null ) { - try { - return metadata.getTypeResolver().heuristicType( typeName, typeParameters ); - } - catch ( Exception ignore ) { - } - } - - return null; - } - - private static final Properties EMPTY_PROPERTIES = new Properties(); - - private Type determineHibernateTypeFromAttributeJavaType( - final SingularAttribute singularAttribute) { - if ( singularAttribute.getSingularAttributeType() != null ) { - return getHeuristicType( - singularAttribute.getSingularAttributeType().getClassName(), - EMPTY_PROPERTIES - ); - } - return null; - } - private void pushHibernateTypeInformationDown( final SingularAttributeSource attributeSource, final SingularAttributeBinding attributeBinding, final Type resolvedHibernateType) { + if ( resolvedHibernateType == null ) { + throw binder.bindingContext().makeMappingException( "Resolved hibernate type can't be null" ); + } + final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding.getHibernateTypeDescriptor(); + if ( hibernateTypeDescriptor.getResolvedTypeMapping() == null ) { + hibernateTypeDescriptor.setResolvedTypeMapping( resolvedHibernateType ); + } // sql type information ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if ( BasicAttributeBinding.class.isInstance( attributeBinding ) ) { @@ -585,22 +643,20 @@ class HibernateTypeHelper { } } + /** + * Resolve domain type for this attribute and also bind jdbc type. + * + * hibernateTypeDescriptor from this binding must already be set with same resolvedHibernateType. + */ private void pushHibernateTypeInformationDown( final BasicAttributeBinding attributeBinding, final Type resolvedHibernateType) { final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding.getHibernateTypeDescriptor(); - final SingularAttribute singularAttribute = SingularAttribute.class.cast( attributeBinding.getAttribute() ); - if ( hibernateTypeDescriptor.getResolvedTypeMapping() != null && hibernateTypeDescriptor.getJavaTypeName() == null ) { - hibernateTypeDescriptor.setJavaTypeName( resolvedHibernateType.getReturnedClass().getName() ); - } + final SingularAttribute singularAttribute = attributeBinding.getAttribute(); if ( !singularAttribute.isTypeResolved() && hibernateTypeDescriptor.getJavaTypeName() != null ) { singularAttribute.resolveType( makeJavaType( hibernateTypeDescriptor.getJavaTypeName() ) ); } - pushHibernateTypeInformationDown( - hibernateTypeDescriptor, - attributeBinding.getRelationalValueBindings(), - resolvedHibernateType - ); + bindJdbcDataType( resolvedHibernateType, attributeBinding.getRelationalValueBindings() ); } @SuppressWarnings({ "UnusedParameters" }) @@ -609,7 +665,8 @@ class HibernateTypeHelper { final CompositeAttributeBinding attributeBinding, final Type resolvedHibernateType) { final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding.getHibernateTypeDescriptor(); - final SingularAttribute singularAttribute = SingularAttribute.class.cast( attributeBinding.getAttribute() ); + + final SingularAttribute singularAttribute = attributeBinding.getAttribute(); if ( !singularAttribute.isTypeResolved() && hibernateTypeDescriptor.getJavaTypeName() != null ) { singularAttribute.resolveType( makeJavaType( hibernateTypeDescriptor.getJavaTypeName() ) ); } @@ -632,46 +689,12 @@ class HibernateTypeHelper { } } - private void pushHibernateTypeInformationDown( - final HibernateTypeDescriptor hibernateTypeDescriptor, - final List relationalValueBindings, - final Type resolvedHibernateType) { - if ( resolvedHibernateType == null ) { - return; - } - if ( hibernateTypeDescriptor.getResolvedTypeMapping() == null ) { - hibernateTypeDescriptor.setResolvedTypeMapping( resolvedHibernateType ); - } - - // java type information ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - if ( hibernateTypeDescriptor.getJavaTypeName() == null ) { - hibernateTypeDescriptor.setJavaTypeName( resolvedHibernateType.getReturnedClass().getName() ); - } - - hibernateTypeDescriptor.setToOne( resolvedHibernateType.isEntityType() ); - - bindJdbcDataType( resolvedHibernateType, relationalValueBindings ); - } private org.hibernate.metamodel.spi.domain.Type makeJavaType(String name) { return binder.bindingContext().makeJavaType( name ); } - private Type resolveCustomCollectionType( - final PluralAttributeBinding pluralAttributeBinding) { - final HibernateTypeDescriptor hibernateTypeDescriptor = pluralAttributeBinding.getHibernateTypeDescriptor(); - Properties typeParameters = new Properties(); - typeParameters.putAll( hibernateTypeDescriptor.getTypeParameters() ); - return metadata.getTypeResolver().getTypeFactory().customCollection( - hibernateTypeDescriptor.getExplicitTypeName(), - typeParameters, - pluralAttributeBinding.getAttribute().getName(), - getReferencedPropertyNameIfNotId( pluralAttributeBinding ), - pluralAttributeBinding.getPluralAttributeElementBinding() - .getNature() == PluralAttributeElementBinding.Nature.AGGREGATE - ); - } + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ private static methods private static String determineTypeName( @@ -681,10 +704,59 @@ class HibernateTypeHelper { : hibernateTypeDescriptor.getJavaTypeName(); } + + private static Class determineJavaType(final SingularAttributeBinding attributeBinding) { + final SingularAttribute attribute = attributeBinding.getAttribute(); + try { + final EntityMode entityMode = attributeBinding.getContainer() + .seekEntityBinding() + .getHierarchyDetails() + .getEntityMode(); + if ( entityMode != EntityMode.POJO ) { + return null; + } + final Class ownerClass = attribute.getAttributeContainer().getClassReference(); + return ReflectHelper.reflectedPropertyClass( ownerClass, attribute.getName() ); + } + catch ( Exception ignore ) { + log.debugf( + "Unable to locate attribute [%s] on class [%s]", + attribute.getName(), + attribute.getAttributeContainer().getClassName() + ); + } + return null; + } + + + private static ReflectedCollectionJavaTypes determineJavaType(PluralAttribute attribute) { + try { + final Class ownerClass = attribute.getAttributeContainer().getClassReference(); + PluralAttributeJavaTypeDeterminerDelegate delegate = new PluralAttributeJavaTypeDeterminerDelegate( + ownerClass, + attribute.getName() + ); + BeanInfoHelper.visitBeanInfo( ownerClass, delegate ); + return delegate.collectionJavaTypes; + } + catch ( Exception ignore ) { + log.debugf( + "Unable to locate attribute [%s] on class [%s]", + attribute.getName(), + attribute.getAttributeContainer().getClassName() + ); + } + return null; + } + + /** + * + * @return type parameters defined in the hibernate type descriptor or {@code empty property}. + */ private static Properties getTypeParameters( final HibernateTypeDescriptor hibernateTypeDescriptor) { if ( CollectionHelper.isEmpty( hibernateTypeDescriptor.getTypeParameters() ) ) { - return EMPTY_PROPERTIES; + return null; } else { Properties typeParameters = new Properties(); @@ -693,6 +765,11 @@ class HibernateTypeHelper { } } + /** + * Find the referenced attribute name, if it is not id attribute. + * @param pluralAttributeBinding Plural attribute binding that has this reference info + * @return Plural attribute referenced attribute name, or null if it is id. + */ private static String getReferencedPropertyNameIfNotId( final PluralAttributeBinding pluralAttributeBinding) { EntityIdentifier entityIdentifier = @@ -758,7 +835,7 @@ class HibernateTypeHelper { elementJavaType = (Class) types[1]; } } - else if ( collectionType.isArray() ) { + else if ( collectionType != null && collectionType.isArray() ) { elementJavaType = collectionType.getComponentType(); } else { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/ManyToManyCollectionTableNamingStrategyHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/ManyToManyCollectionTableNamingStrategyHelper.java new file mode 100644 index 0000000000..4281a5df58 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/ManyToManyCollectionTableNamingStrategyHelper.java @@ -0,0 +1,86 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2012, 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; + +import org.hibernate.cfg.NamingStrategy; +import org.hibernate.metamodel.spi.binding.AbstractPluralAttributeBinding; +import org.hibernate.metamodel.spi.binding.EntityBinding; +import org.hibernate.metamodel.spi.relational.Table; +import org.hibernate.metamodel.spi.source.TableSpecificationSource; + +/** + * @author Strong Liu + */ +public class ManyToManyCollectionTableNamingStrategyHelper extends TableNamingStrategyHelper { + private final EntityBinding ownerEntityBinding; + private final EntityBinding inverseEntityBinding; + private final String ownerTableLogicalName; + private final String inverseTableLogicalName; + private final String propertyName; + + public ManyToManyCollectionTableNamingStrategyHelper( + final AbstractPluralAttributeBinding pluralAttributeBinding, + final boolean isInverse, + final EntityBinding associatedEntityBinding) { + super( pluralAttributeBinding.getContainer().seekEntityBinding() ); + if ( isInverse ) { + ownerEntityBinding = associatedEntityBinding; + inverseEntityBinding = entityBinding; + } + else { + ownerEntityBinding = entityBinding; + inverseEntityBinding = associatedEntityBinding; + } + ownerTableLogicalName = + Table.class.isInstance( ownerEntityBinding.getPrimaryTable() ) + ? ( (Table) ownerEntityBinding.getPrimaryTable() ).getPhysicalName().getText() + : null; + inverseTableLogicalName = + Table.class.isInstance( inverseEntityBinding.getPrimaryTable() ) + ? ( (Table) inverseEntityBinding.getPrimaryTable() ).getPhysicalName().getText() + : null; + propertyName = Binder.createAttributePath( pluralAttributeBinding ); + } + + @Override + public String determineImplicitName(NamingStrategy strategy) { + return strategy.collectionTableName( + ownerEntityBinding.getEntity().getName(), + ownerTableLogicalName, + inverseEntityBinding.getEntity().getName(), + inverseTableLogicalName, + propertyName + ); + } + + @Override + public String getLogicalName(NamingStrategy strategy) { + return strategy.logicalCollectionTableName( + logicalName, + ownerEntityBinding.getEntity().getName(), + inverseEntityBinding.getEntity().getName(), + propertyName + ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/TableNamingStrategyHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/TableNamingStrategyHelper.java new file mode 100644 index 0000000000..3e25a6bde5 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/TableNamingStrategyHelper.java @@ -0,0 +1,65 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2010, 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; + +import org.hibernate.cfg.NamingStrategy; +import org.hibernate.cfg.ObjectNameNormalizer; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.metamodel.spi.binding.EntityBinding; + +/** + * @author Strong Liu + */ +class TableNamingStrategyHelper implements ObjectNameNormalizer.LogicalNamingStrategyHelper { + protected final EntityBinding entityBinding; + protected final String entityName; + protected String logicalName; + + TableNamingStrategyHelper(EntityBinding entityBinding) { + this.entityBinding = entityBinding; + this.entityName = getImplicitTableName(); + } + + @Override + public String determineImplicitName(NamingStrategy strategy) { + String name = getImplicitTableName(); + return strategy.classToTableName( name ); + } + + protected String getImplicitTableName() { + return StringHelper.isNotEmpty( entityBinding.getJpaEntityName() ) ? entityBinding.getJpaEntityName() : entityBinding + .getEntity().getName(); + } + + @Override + public String handleExplicitName(NamingStrategy strategy, String tableName) { + this.logicalName = tableName; + return strategy.tableName( tableName ); + } + + @Override + public String getLogicalName(NamingStrategy strategy) { + return logicalName == null ? entityName : logicalName; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractToOneAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractToOneAttributeSourceImpl.java index 506fdc48cb..d6654be929 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractToOneAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractToOneAttributeSourceImpl.java @@ -165,7 +165,10 @@ public abstract class AbstractToOneAttributeSourceImpl extends AbstractHbmSource @Override // TODO: change to return the default name for a single column - public List getDefaultNamingStrategies(final String entityName, final String tableName, final AttributeBinding referencedAttributeBinding) { + public List getDefaultNamingStrategies( + final String entityName, + final String tableName, + final AttributeBinding referencedAttributeBinding) { if ( CompositeAttributeBinding.class.isInstance( referencedAttributeBinding ) ) { CompositeAttributeBinding compositeAttributeBinding = CompositeAttributeBinding.class.cast( referencedAttributeBinding diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/HibernateTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/HibernateTypeDescriptor.java index 07578f3398..b52a360115 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/HibernateTypeDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/HibernateTypeDescriptor.java @@ -35,11 +35,12 @@ import org.hibernate.type.Type; */ public class HibernateTypeDescriptor { private String explicitTypeName; - private String javaTypeName; - private boolean isToOne; private Map typeParameters = new HashMap( ); + private Type resolvedTypeMapping; + private String javaTypeName; + private boolean isToOne; public String getExplicitTypeName() { return explicitTypeName; @@ -62,22 +63,22 @@ public class HibernateTypeDescriptor { } public void setToOne(boolean toOne) { - isToOne = toOne; + this.isToOne = toOne; } public Map getTypeParameters() { return typeParameters; } - public void setTypeParameters(Map typeParameters) { - this.typeParameters = typeParameters; - } - public Type getResolvedTypeMapping() { return resolvedTypeMapping; } public void setResolvedTypeMapping(Type resolvedTypeMapping) { this.resolvedTypeMapping = resolvedTypeMapping; + if ( getJavaTypeName() == null && resolvedTypeMapping!=null ) { + setJavaTypeName( resolvedTypeMapping.getReturnedClass().getName() ); + setToOne( resolvedTypeMapping.isEntityType() ); + } } } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/junit4/BaseCoreFunctionalTestCase.java b/hibernate-testing/src/main/java/org/hibernate/testing/junit4/BaseCoreFunctionalTestCase.java index 55090e3946..9c121113a9 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/junit4/BaseCoreFunctionalTestCase.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/junit4/BaseCoreFunctionalTestCase.java @@ -46,6 +46,7 @@ import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl; import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.EJB3NamingStrategy; import org.hibernate.cfg.Environment; import org.hibernate.cfg.Mappings; import org.hibernate.dialect.Dialect; @@ -61,6 +62,7 @@ import org.hibernate.mapping.Collection; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; import org.hibernate.mapping.SimpleValue; +import org.hibernate.metamodel.MetadataBuilder; import org.hibernate.metamodel.MetadataSources; import org.hibernate.metamodel.SessionFactoryBuilder; import org.hibernate.metamodel.spi.MetadataImplementor; @@ -161,13 +163,13 @@ public abstract class BaseCoreFunctionalTestCase extends BaseUnitTestCase { true ); if ( isMetadataUsed ) { - metadataImplementor = buildMetadata( bootRegistry, serviceRegistry ); + MetadataBuilder metadataBuilder = getMetadataBuilder( bootRegistry, serviceRegistry ); + configMetadataBuilder(metadataBuilder, configuration); + metadataImplementor = (MetadataImplementor)metadataBuilder.build(); afterConstructAndConfigureMetadata( metadataImplementor ); applyCacheSettings(metadataImplementor); SessionFactoryBuilder sessionFactoryBuilder = metadataImplementor.getSessionFactoryBuilder(); - if(configuration.getEntityNotFoundDelegate()!=null){ - sessionFactoryBuilder.with( configuration.getEntityNotFoundDelegate() ); - } + configSessionFactoryBuilder(sessionFactoryBuilder, configuration); sessionFactory = ( SessionFactoryImplementor )sessionFactoryBuilder.build(); } else { @@ -178,6 +180,19 @@ public abstract class BaseCoreFunctionalTestCase extends BaseUnitTestCase { afterSessionFactoryBuilt(); } + protected void configMetadataBuilder(MetadataBuilder metadataBuilder, Configuration configuration) { + //see if the naming strategy is the default one + if ( configuration.getNamingStrategy() != EJB3NamingStrategy.INSTANCE ) { + metadataBuilder.with( configuration.getNamingStrategy() ); + } + } + + protected void configSessionFactoryBuilder(SessionFactoryBuilder sessionFactoryBuilder, Configuration configuration) { + if ( configuration.getEntityNotFoundDelegate() != null ) { + sessionFactoryBuilder.with( configuration.getEntityNotFoundDelegate() ); + } + } + protected void rebuildSessionFactory() { if ( sessionFactory == null ) { return; @@ -190,12 +205,12 @@ public abstract class BaseCoreFunctionalTestCase extends BaseUnitTestCase { } - private MetadataImplementor buildMetadata( + protected MetadataBuilder getMetadataBuilder( BootstrapServiceRegistry bootRegistry, StandardServiceRegistryImpl serviceRegistry) { MetadataSources sources = new MetadataSources( bootRegistry ); addMappings( sources ); - return (MetadataImplementor) sources.getMetadataBuilder( serviceRegistry ).build(); + return sources.getMetadataBuilder(serviceRegistry); } private Configuration constructAndConfigureConfiguration() {