diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionElement.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractCollectionElement.java similarity index 70% rename from hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionElement.java rename to hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractCollectionElement.java index 8a1c27b965..1b922133cf 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionElement.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractCollectionElement.java @@ -26,23 +26,21 @@ package org.hibernate.metamodel.binding; import org.hibernate.metamodel.relational.Value; /** - * TODO : javadoc + * Basic contract describing the commonality between the various types of collection element mappings. * * @author Steve Ebersole */ -public abstract class CollectionElement { +public abstract class AbstractCollectionElement { private final AbstractPluralAttributeBinding collectionBinding; - private final CollectionElementNature collectionElementNature; - - private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor(); private Value elementValue; - CollectionElement(AbstractPluralAttributeBinding collectionBinding, CollectionElementNature collectionElementNature) { + AbstractCollectionElement(AbstractPluralAttributeBinding collectionBinding) { this.collectionBinding = collectionBinding; - this.collectionElementNature = collectionElementNature; } + public abstract CollectionElementNature getCollectionElementNature(); + public AbstractPluralAttributeBinding getCollectionBinding() { return collectionBinding; } @@ -50,12 +48,4 @@ public abstract class CollectionElement { public Value getElementValue() { return elementValue; } - - public final CollectionElementNature getCollectionElementNature() { - return collectionElementNature; - } - - public HibernateTypeDescriptor getHibernateTypeDescriptor() { - return hibernateTypeDescriptor; - } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractPluralAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractPluralAttributeBinding.java index dfe6194d35..0119b99d9e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractPluralAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractPluralAttributeBinding.java @@ -32,8 +32,10 @@ import java.util.List; import org.hibernate.AssertionFailure; import org.hibernate.FetchMode; import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.metamodel.domain.Attribute; import org.hibernate.metamodel.domain.PluralAttribute; import org.hibernate.metamodel.relational.Table; +import org.hibernate.metamodel.relational.TableSpecification; /** * TODO : javadoc @@ -42,7 +44,7 @@ import org.hibernate.metamodel.relational.Table; */ public abstract class AbstractPluralAttributeBinding extends AbstractAttributeBinding implements PluralAttributeBinding { private final CollectionKey collectionKey; - private final CollectionElement collectionElement; + private final AbstractCollectionElement collectionElement; private Table collectionTable; @@ -85,7 +87,7 @@ public abstract class AbstractPluralAttributeBinding extends AbstractAttributeBi this.collectionElement = interpretNature( collectionElementNature ); } - private CollectionElement interpretNature(CollectionElementNature collectionElementNature) { + private AbstractCollectionElement interpretNature(CollectionElementNature collectionElementNature) { switch ( collectionElementNature ) { case BASIC: { return new BasicCollectionElement( this ); @@ -142,6 +144,11 @@ public abstract class AbstractPluralAttributeBinding extends AbstractAttributeBi // loaderName = state.getLoaderName(); // } + @Override + public PluralAttribute getAttribute() { + return (PluralAttribute) super.getAttribute(); + } + @Override public boolean isAssociation() { return collectionElement.getCollectionElementNature() == CollectionElementNature.MANY_TO_ANY @@ -149,7 +156,7 @@ public abstract class AbstractPluralAttributeBinding extends AbstractAttributeBi || collectionElement.getCollectionElementNature() == CollectionElementNature.ONE_TO_MANY; } - public Table getCollectionTable() { + public TableSpecification getCollectionTable() { return collectionTable; } @@ -161,7 +168,7 @@ public abstract class AbstractPluralAttributeBinding extends AbstractAttributeBi return collectionKey; } - public CollectionElement getCollectionElement() { + public AbstractCollectionElement getCollectionElement() { return collectionElement; } @@ -229,10 +236,18 @@ public abstract class AbstractPluralAttributeBinding extends AbstractAttributeBi return orderBy; } + public void setOrderBy(String orderBy) { + this.orderBy = orderBy; + } + public String getWhere() { return where; } + public void setWhere(String where) { + this.where = where; + } + public String getReferencedPropertyName() { return referencedPropertyName; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/BasicCollectionElement.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/BasicCollectionElement.java index 277aeda19c..5d0f84c216 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/BasicCollectionElement.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/BasicCollectionElement.java @@ -24,10 +24,21 @@ package org.hibernate.metamodel.binding; /** + * @author Steve Ebersole * @author Gail Badner */ -public class BasicCollectionElement extends CollectionElement { +public class BasicCollectionElement extends AbstractCollectionElement { + private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor(); + public BasicCollectionElement(AbstractPluralAttributeBinding binding) { - super( binding, CollectionElementNature.BASIC ); + super( binding ); + } + + public CollectionElementNature getCollectionElementNature() { + return CollectionElementNature.BASIC; + } + + public HibernateTypeDescriptor getHibernateTypeDescriptor() { + return hibernateTypeDescriptor; } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionKey.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionKey.java index 61c7aef096..81661e8e23 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionKey.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionKey.java @@ -23,7 +23,9 @@ */ package org.hibernate.metamodel.binding; +import org.hibernate.AssertionFailure; import org.hibernate.metamodel.relational.ForeignKey; +import org.hibernate.metamodel.relational.TableSpecification; /** * TODO : javadoc @@ -31,7 +33,7 @@ import org.hibernate.metamodel.relational.ForeignKey; * @author Steve Ebersole */ public class CollectionKey { - private final AbstractPluralAttributeBinding collection; + private final AbstractPluralAttributeBinding pluralAttributeBinding; private ForeignKey foreignKey; private boolean inverse; @@ -40,7 +42,33 @@ public class CollectionKey { // todo : this would be nice to have but we do not always know it, especially in HBM case. // private BasicAttributeBinding otherSide; - public CollectionKey(AbstractPluralAttributeBinding collection) { - this.collection = collection; + public CollectionKey(AbstractPluralAttributeBinding pluralAttributeBinding) { + this.pluralAttributeBinding = pluralAttributeBinding; + } + + public AbstractPluralAttributeBinding getPluralAttributeBinding() { + return pluralAttributeBinding; + } + + public void prepareForeignKey(String foreignKeyName, String targetTableName) { + if ( foreignKey != null ) { + throw new AssertionFailure( "Foreign key already initialized" ); + } + final TableSpecification collectionTable = pluralAttributeBinding.getCollectionTable(); + if ( collectionTable == null ) { + throw new AssertionFailure( "Collection table not yet bound" ); + } + + final TableSpecification targetTable = pluralAttributeBinding.getContainer() + .seekEntityBinding() + .locateTable( targetTableName ); + + // todo : handle implicit fk names... + + foreignKey = collectionTable.createForeignKey( targetTable, foreignKeyName ); + } + + public ForeignKey getForeignKey() { + return foreignKey; } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CompositeCollectionElement.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CompositeCollectionElement.java index 2b100ea00e..e39886d055 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CompositeCollectionElement.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CompositeCollectionElement.java @@ -24,10 +24,16 @@ package org.hibernate.metamodel.binding; /** + * @author Steve Ebersole * @author Gail Badner */ -public class CompositeCollectionElement extends CollectionElement { +public class CompositeCollectionElement extends AbstractCollectionElement { public CompositeCollectionElement(AbstractPluralAttributeBinding binding) { - super( binding, CollectionElementNature.COMPOSITE ); + super( binding ); + } + + @Override + public CollectionElementNature getCollectionElementNature() { + return CollectionElementNature.COMPOSITE; } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ManyToAnyCollectionElement.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ManyToAnyCollectionElement.java index 42a3904318..50e5edd443 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ManyToAnyCollectionElement.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ManyToAnyCollectionElement.java @@ -24,10 +24,16 @@ package org.hibernate.metamodel.binding; /** + * @author Steve Ebersole * @author Gail Badner */ -public class ManyToAnyCollectionElement extends CollectionElement { +public class ManyToAnyCollectionElement extends AbstractCollectionElement { ManyToAnyCollectionElement(AbstractPluralAttributeBinding binding) { - super( binding, CollectionElementNature.MANY_TO_ANY ); + super( binding ); + } + + @Override + public CollectionElementNature getCollectionElementNature() { + return CollectionElementNature.MANY_TO_ANY; } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ManyToManyCollectionElement.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ManyToManyCollectionElement.java index bb75aa035c..ee5b93464a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ManyToManyCollectionElement.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ManyToManyCollectionElement.java @@ -28,9 +28,10 @@ import java.util.HashMap; import org.dom4j.Element; /** + * @author Steve Ebersole * @author Gail Badner */ -public class ManyToManyCollectionElement extends CollectionElement { +public class ManyToManyCollectionElement extends AbstractCollectionElement { private final java.util.Map manyToManyFilters = new HashMap(); private String manyToManyWhere; @@ -38,7 +39,12 @@ public class ManyToManyCollectionElement extends CollectionElement { ManyToManyCollectionElement(AbstractPluralAttributeBinding binding) { - super( binding, CollectionElementNature.MANY_TO_MANY ); + super( binding ); + } + + @Override + public CollectionElementNature getCollectionElementNature() { + return CollectionElementNature.MANY_TO_MANY; } public void fromHbmXml(Element node){ diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/OneToManyCollectionElement.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/OneToManyCollectionElement.java index 0655ae788c..a2b38037fd 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/OneToManyCollectionElement.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/OneToManyCollectionElement.java @@ -24,11 +24,17 @@ package org.hibernate.metamodel.binding; /** + * @author Steve Ebersole * @author Gail Badner */ -public class OneToManyCollectionElement extends CollectionElement { +public class OneToManyCollectionElement extends AbstractCollectionElement { OneToManyCollectionElement(AbstractPluralAttributeBinding binding) { - super( binding, CollectionElementNature.ONE_TO_MANY ); + super( binding ); + } + + @Override + public CollectionElementNature getCollectionElementNature() { + return CollectionElementNature.ONE_TO_MANY; } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/PluralAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/PluralAttributeBinding.java index 348ddf3bf4..0db73c2d28 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/PluralAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/PluralAttributeBinding.java @@ -23,7 +23,7 @@ */ package org.hibernate.metamodel.binding; -import org.hibernate.metamodel.relational.Table; +import org.hibernate.metamodel.relational.TableSpecification; import org.hibernate.persister.collection.CollectionPersister; /** @@ -34,9 +34,9 @@ public interface PluralAttributeBinding extends AttributeBinding, AssociationAtt public CollectionKey getCollectionKey(); - public CollectionElement getCollectionElement(); + public AbstractCollectionElement getCollectionElement(); - public Table getCollectionTable(); + public TableSpecification getCollectionTable(); public boolean isMutable(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/relational/Database.java b/hibernate-core/src/main/java/org/hibernate/metamodel/relational/Database.java index 9b5490815d..f15f565790 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/relational/Database.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/relational/Database.java @@ -64,7 +64,7 @@ public class Database { return schemaMap.get( implicitSchemaName ); } - public Schema getSchema(Schema.Name name) { + public Schema locateSchema(Schema.Name name) { if ( name.getSchema() == null && name.getCatalog() == null ) { return getDefaultSchema(); } @@ -83,11 +83,11 @@ public class Database { } public Schema getSchema(Identifier schema, Identifier catalog) { - return getSchema( new Schema.Name( schema, catalog ) ); + return locateSchema( new Schema.Name( schema, catalog ) ); } public Schema getSchema(String schema, String catalog) { - return getSchema( new Schema.Name( Identifier.toIdentifier( schema ), Identifier.toIdentifier( catalog ) ) ); + return locateSchema( new Schema.Name( Identifier.toIdentifier( schema ), Identifier.toIdentifier( catalog ) ) ); } public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject auxiliaryDatabaseObject) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/relational/Table.java b/hibernate-core/src/main/java/org/hibernate/metamodel/relational/Table.java index ab9d4c5475..5cc0e98409 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/relational/Table.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/relational/Table.java @@ -28,6 +28,7 @@ import java.util.LinkedHashMap; import java.util.List; import org.hibernate.dialect.Dialect; +import org.hibernate.internal.util.StringHelper; /** * Models the concept of a relational TABLE (or VIEW). diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/Binder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/Binder.java index 5f7515a511..5ceffbad15 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/Binder.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/Binder.java @@ -25,7 +25,10 @@ package org.hibernate.metamodel.source.binder; import java.beans.BeanInfo; import java.beans.PropertyDescriptor; +import java.lang.reflect.Member; +import java.lang.reflect.ParameterizedType; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Map; @@ -34,14 +37,17 @@ import org.hibernate.EntityMode; import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.beans.BeanInfoHelper; +import org.hibernate.metamodel.binding.AbstractCollectionElement; import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding; import org.hibernate.metamodel.binding.AttributeBinding; import org.hibernate.metamodel.binding.AttributeBindingContainer; import org.hibernate.metamodel.binding.BasicAttributeBinding; +import org.hibernate.metamodel.binding.BasicCollectionElement; import org.hibernate.metamodel.binding.CollectionElementNature; import org.hibernate.metamodel.binding.ComponentAttributeBinding; import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.EntityDiscriminator; +import org.hibernate.metamodel.binding.HibernateTypeDescriptor; import org.hibernate.metamodel.binding.InheritanceType; import org.hibernate.metamodel.binding.ManyToOneAttributeBinding; import org.hibernate.metamodel.binding.MetaAttribute; @@ -53,6 +59,7 @@ import org.hibernate.metamodel.domain.Component; import org.hibernate.metamodel.domain.Entity; import org.hibernate.metamodel.domain.PluralAttribute; import org.hibernate.metamodel.domain.SingularAttribute; +import org.hibernate.metamodel.domain.Type; import org.hibernate.metamodel.relational.Column; import org.hibernate.metamodel.relational.DerivedValue; import org.hibernate.metamodel.relational.Identifier; @@ -440,8 +447,8 @@ public class Binder { private void bindPersistentCollection(PluralAttributeSource attributeSource, AttributeBindingContainer attributeBindingContainer) { final PluralAttribute existingAttribute = attributeBindingContainer.getAttributeContainer().locatePluralAttribute( - attributeSource.getName() - ); + attributeSource.getName() + ); final AbstractPluralAttributeBinding pluralAttributeBinding; if ( attributeSource.getPluralAttributeNature() == PluralAttributeNature.BAG ) { @@ -467,15 +474,34 @@ public class Binder { throw new NotYetImplementedException( "Collections other than bag not yet implemented :(" ); } - doBasicAttributeBinding( attributeSource, pluralAttributeBinding ); + doBasicPluralAttributeBinding( attributeSource, pluralAttributeBinding ); bindCollectionTable( attributeSource, pluralAttributeBinding ); - bindCollectionKey( attributeSource, pluralAttributeBinding ); bindSortingAndOrdering( attributeSource, pluralAttributeBinding ); + bindCollectionKey( attributeSource, pluralAttributeBinding ); + bindCollectionElement( attributeSource, pluralAttributeBinding ); + bindCollectionIndex( attributeSource, pluralAttributeBinding ); + metadata.addCollection( pluralAttributeBinding ); } + private void doBasicPluralAttributeBinding( + PluralAttributeSource attributeSource, + AbstractPluralAttributeBinding pluralAttributeBinding) { + pluralAttributeBinding.setFetchMode( attributeSource.getFetchMode() ); + pluralAttributeBinding.setCascadeStyles( attributeSource.getCascadeStyles() ); + + pluralAttributeBinding.setMetaAttributeContext( + buildMetaAttributeContext( + attributeSource.metaAttributes(), + pluralAttributeBinding.getContainer().getMetaAttributeContext() + ) + ); + + doBasicAttributeBinding( attributeSource, pluralAttributeBinding ); + } + private void bindCollectionTable( PluralAttributeSource attributeSource, AbstractPluralAttributeBinding pluralAttributeBinding) { @@ -483,23 +509,101 @@ public class Binder { return; } - if ( StringHelper.isNotEmpty( attributeSource.getExplicitCollectionTableName() ) ) { - final Identifier tableIdentifier = Identifier.toIdentifier( attributeSource.getExplicitCollectionTableName() ); - Table collectionTable = metadata.getDatabase().getDefaultSchema().locateTable( tableIdentifier ); + final Schema.Name schemaName = Helper.determineDatabaseSchemaName( + attributeSource.getExplicitSchemaName(), + attributeSource.getExplicitCatalogName(), + currentBindingContext + ); + final Schema schema = metadata.getDatabase().locateSchema( schemaName ); + + final String tableName = attributeSource.getExplicitCollectionTableName(); + if ( StringHelper.isNotEmpty( tableName ) ) { + final Identifier tableIdentifier = Identifier.toIdentifier( currentBindingContext.getNamingStrategy().tableName( + tableName + ) ); + Table collectionTable = schema.locateTable( tableIdentifier ); if ( collectionTable == null ) { - collectionTable = metadata.getDatabase().getDefaultSchema().createTable( tableIdentifier ); + collectionTable = schema.createTable( tableIdentifier ); } pluralAttributeBinding.setCollectionTable( collectionTable ); } else { - // todo : we need to infer the name, but that requires possibly knowing the other side + // todo : not sure wel have all the needed info here in all cases, specifically when needing to know the "other side" + final EntityBinding owner = pluralAttributeBinding.getContainer().seekEntityBinding(); + final String ownerTableLogicalName = Table.class.isInstance( owner.getPrimaryTable() ) + ? Table.class.cast( owner.getPrimaryTable() ).getTableName().getName() + : null; + String collectionTableName = currentBindingContext.getNamingStrategy().collectionTableName( + owner.getEntity().getName(), + ownerTableLogicalName, + null, // todo : here + null, // todo : and here + pluralAttributeBinding.getContainer().getPathBase() + '.' + attributeSource.getName() + ); + if ( currentBindingContext.isGloballyQuotedIdentifiers() ) { + collectionTableName = StringHelper.quote( collectionTableName ); + } + pluralAttributeBinding.setCollectionTable( schema.locateOrCreateTable( Identifier.toIdentifier( collectionTableName ) ) ); } + + if ( StringHelper.isNotEmpty( attributeSource.getCollectionTableComment() ) ) { + pluralAttributeBinding.getCollectionTable().addComment( attributeSource.getCollectionTableComment() ); + } + + if ( StringHelper.isNotEmpty( attributeSource.getCollectionTableCheck() ) ) { + pluralAttributeBinding.getCollectionTable().addCheckConstraint( attributeSource.getCollectionTableCheck() ); + } + + pluralAttributeBinding.setWhere( attributeSource.getWhere() ); } private void bindCollectionKey( PluralAttributeSource attributeSource, AbstractPluralAttributeBinding pluralAttributeBinding) { + pluralAttributeBinding.getCollectionKey().prepareForeignKey( + attributeSource.getKeySource().getExplicitForeignKeyName(), + null // todo : handle secondary table names + ); + pluralAttributeBinding.getCollectionKey().getForeignKey().setDeleteRule( + attributeSource.getKeySource().getOnDeleteAction() + ); + // todo : need to bind "relational values", account for property-ref + } + + private void bindCollectionElement( + PluralAttributeSource attributeSource, + AbstractPluralAttributeBinding pluralAttributeBinding) { + final PluralAttributeElementSource elementSource = attributeSource.getElementSource(); + if ( elementSource.getNature() == PluralAttributeElementNature.BASIC ) { + final BasicPluralAttributeElementSource basicElementSource = (BasicPluralAttributeElementSource) elementSource; + final BasicCollectionElement basicCollectionElement = (BasicCollectionElement) pluralAttributeBinding.getCollectionElement(); + resolveTypeInformation( + basicElementSource.getExplicitHibernateTypeSource(), + pluralAttributeBinding.getAttribute(), + basicCollectionElement + ); + // todo : temp + return; + } // todo : implement + throw new NotYetImplementedException( + String.format( + "Support for collection elements of type %s not yet implemented", + elementSource.getNature() + ) + ); + } + + private void bindCollectionIndex( + PluralAttributeSource attributeSource, + AbstractPluralAttributeBinding pluralAttributeBinding) { + if ( attributeSource.getPluralAttributeNature() != PluralAttributeNature.LIST + && attributeSource.getPluralAttributeNature() != PluralAttributeNature.MAP ) { + return; + } + + // todo : implement + throw new NotYetImplementedException(); } private void bindSortingAndOrdering( @@ -536,8 +640,8 @@ public class Binder { SingularAttributeSource attributeSource, AttributeBindingContainer attributeBindingContainer) { final SingularAttribute existingAttribute = attributeBindingContainer.getAttributeContainer().locateSingularAttribute( - attributeSource.getName() - ); + attributeSource.getName() + ); final SingularAttribute attribute; if ( existingAttribute != null ) { attribute = existingAttribute; @@ -590,36 +694,55 @@ public class Binder { private void resolveTypeInformation(ExplicitHibernateTypeSource typeSource, BasicAttributeBinding attributeBinding) { final Class attributeJavaType = determineJavaType( attributeBinding.getAttribute() ); if ( attributeJavaType != null ) { - attributeBinding.getHibernateTypeDescriptor().setJavaTypeName( attributeJavaType.getName() ); attributeBinding.getAttribute() .resolveType( currentBindingContext.makeJavaType( attributeJavaType.getName() ) ); } + resolveTypeInformation( typeSource, attributeBinding.getHibernateTypeDescriptor(), attributeJavaType ); + } + + private void resolveTypeInformation( + ExplicitHibernateTypeSource typeSource, + PluralAttribute attribute, + BasicCollectionElement collectionElement) { + final Class attributeJavaType = determineJavaType( attribute ); + + resolveTypeInformation( typeSource, collectionElement.getHibernateTypeDescriptor(), attributeJavaType ); + } + + private void resolveTypeInformation( + ExplicitHibernateTypeSource typeSource, + HibernateTypeDescriptor hibernateTypeDescriptor, + Class discoveredJavaType) { + if ( discoveredJavaType != null ) { + hibernateTypeDescriptor.setJavaTypeName( discoveredJavaType.getName() ); + } + final String explicitTypeName = typeSource.getName(); if ( explicitTypeName != null ) { final TypeDef typeDef = currentBindingContext.getMetadataImplementor() .getTypeDefinition( explicitTypeName ); if ( typeDef != null ) { - attributeBinding.getHibernateTypeDescriptor().setExplicitTypeName( typeDef.getTypeClass() ); - attributeBinding.getHibernateTypeDescriptor().getTypeParameters().putAll( typeDef.getParameters() ); + hibernateTypeDescriptor.setExplicitTypeName( typeDef.getTypeClass() ); + hibernateTypeDescriptor.getTypeParameters().putAll( typeDef.getParameters() ); } else { - attributeBinding.getHibernateTypeDescriptor().setExplicitTypeName( explicitTypeName ); + hibernateTypeDescriptor.setExplicitTypeName( explicitTypeName ); } final Map parameters = typeSource.getParameters(); if ( parameters!=null) { - attributeBinding.getHibernateTypeDescriptor().getTypeParameters().putAll( parameters ); + hibernateTypeDescriptor.getTypeParameters().putAll( parameters ); } } else { - if ( attributeJavaType == null ) { + if ( discoveredJavaType == null ) { // we will have problems later determining the Hibernate Type to use. Should we throw an // exception now? Might be better to get better contextual info } } } - private Class determineJavaType(final Attribute attribute) { + private Class determineJavaType(final SingularAttribute attribute) { try { final Class ownerClass = attribute.getAttributeContainer().getClassReference(); AttributeJavaTypeDeterminerDelegate delegate = new AttributeJavaTypeDeterminerDelegate( attribute.getName() ); @@ -651,6 +774,76 @@ public class Binder { } } + private Class determineJavaType(PluralAttribute attribute) { + try { + final Class ownerClass = attribute.getAttributeContainer().getClassReference(); + PluralAttributeJavaTypeDeterminerDelegate delegate = new PluralAttributeJavaTypeDeterminerDelegate( ownerClass, attribute.getName() ); + BeanInfoHelper.visitBeanInfo( ownerClass, delegate ); + return delegate.javaType; + } + catch ( Exception ignore ) { + // todo : log it? + } + return null; + } + + private class PluralAttributeJavaTypeDeterminerDelegate implements BeanInfoHelper.BeanInfoDelegate { + private final Class ownerClass; + private final String attributeName; + + private Class javaType = null; + + private PluralAttributeJavaTypeDeterminerDelegate(Class ownerClass, String attributeName) { + this.ownerClass = ownerClass; + this.attributeName = attributeName; + } + + @Override + public void processBeanInfo(BeanInfo beanInfo) throws Exception { + for ( PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors() ) { + if ( propertyDescriptor.getName().equals( attributeName ) ) { + javaType = extractCollectionComponentType( beanInfo, propertyDescriptor ); + break; + } + } + } + + @SuppressWarnings( {"unchecked"}) + private Class extractCollectionComponentType(BeanInfo beanInfo, PropertyDescriptor propertyDescriptor) { + final java.lang.reflect.Type collectionAttributeType; + if ( propertyDescriptor.getReadMethod() != null ) { + collectionAttributeType = propertyDescriptor.getReadMethod().getGenericReturnType(); + } + else if ( propertyDescriptor.getWriteMethod() != null ) { + collectionAttributeType = propertyDescriptor.getWriteMethod().getGenericParameterTypes()[0]; + } + else { + // we need to look for the field and look at it... + try { + collectionAttributeType = ownerClass.getField( propertyDescriptor.getName() ).getGenericType(); + } + catch (Exception e) { + return null; + } + } + + if ( ParameterizedType.class.isInstance( collectionAttributeType ) ) { + final java.lang.reflect.Type[] types = ( (ParameterizedType) collectionAttributeType ).getActualTypeArguments(); + if ( types == null ) { + return null; + } + else if ( types.length == 1 ) { + return (Class) types[0]; + } + else if ( types.length == 2 ) { + // Map + return (Class) types[1]; + } + } + return null; + } + } + private void resolveToOneInformation(ToOneAttributeSource attributeSource, ManyToOneAttributeBinding attributeBinding) { final String referencedEntityName = attributeSource.getReferencedEntityName() != null ? attributeSource.getReferencedEntityName() @@ -718,17 +911,6 @@ public class Binder { } private Table createTable(EntityBinding entityBinding, TableSource tableSource) { - final String schemaName = StringHelper.isEmpty( tableSource.getExplicitSchemaName() ) - ? currentBindingContext.getMappingDefaults().getSchemaName() - : currentBindingContext.isGloballyQuotedIdentifiers() - ? StringHelper.quote( tableSource.getExplicitSchemaName() ) - : tableSource.getExplicitSchemaName(); - final String catalogName = StringHelper.isEmpty( tableSource.getExplicitCatalogName() ) - ? currentBindingContext.getMappingDefaults().getCatalogName() - : currentBindingContext.isGloballyQuotedIdentifiers() - ? StringHelper.quote( tableSource.getExplicitCatalogName() ) - : tableSource.getExplicitCatalogName(); - String tableName = tableSource.getExplicitTableName(); if ( StringHelper.isEmpty( tableName ) ) { tableName = currentBindingContext.getNamingStrategy() @@ -741,9 +923,14 @@ public class Binder { tableName = StringHelper.quote( tableName ); } + final Schema.Name databaseSchemaName = Helper.determineDatabaseSchemaName( + tableSource.getExplicitSchemaName(), + tableSource.getExplicitCatalogName(), + currentBindingContext + ); return currentBindingContext.getMetadataImplementor() .getDatabase() - .getSchema( new Schema.Name( schemaName, catalogName ) ) + .locateSchema( databaseSchemaName ) .locateOrCreateTable( Identifier.toIdentifier( tableName ) ); } @@ -847,5 +1034,4 @@ public class Binder { private void processFetchProfiles(EntitySource entitySource, EntityBinding entityBinding) { // todo : process the entity-local fetch-profile declaration } - } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/PluralAttributeSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/PluralAttributeSource.java index 2c5673497b..7a01606811 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/PluralAttributeSource.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/PluralAttributeSource.java @@ -33,7 +33,14 @@ public interface PluralAttributeSource extends AssociationAttributeSource { public PluralAttributeElementSource getElementSource(); + public String getExplicitSchemaName(); + public String getExplicitCatalogName(); public String getExplicitCollectionTableName(); + public String getCollectionTableComment(); + public String getCollectionTableCheck(); + + public String getWhere(); + public boolean isInverse(); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/AbstractPluralAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/AbstractPluralAttributeSourceImpl.java index 25fbedbf4f..baf606c12f 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/AbstractPluralAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/AbstractPluralAttributeSourceImpl.java @@ -23,18 +23,73 @@ */ package org.hibernate.metamodel.source.hbm; +import org.hibernate.FetchMode; +import org.hibernate.cfg.NotYetImplementedException; +import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.metamodel.source.LocalBindingContext; +import org.hibernate.metamodel.source.MappingException; import org.hibernate.metamodel.source.binder.AttributeSourceContainer; +import org.hibernate.metamodel.source.binder.MetaAttributeSource; +import org.hibernate.metamodel.source.binder.PluralAttributeElementSource; +import org.hibernate.metamodel.source.binder.PluralAttributeKeySource; import org.hibernate.metamodel.source.binder.PluralAttributeSource; +import org.hibernate.metamodel.source.hbm.jaxb.mapping.PluralAttributeElement; /** * @author Steve Ebersole */ public abstract class AbstractPluralAttributeSourceImpl implements PluralAttributeSource { + private final PluralAttributeElement pluralAttributeElement; private final AttributeSourceContainer container; - protected AbstractPluralAttributeSourceImpl(AttributeSourceContainer container) { + private final PluralAttributeKeySource keySource; + private final PluralAttributeElementSource elementSource; + + protected AbstractPluralAttributeSourceImpl( + PluralAttributeElement pluralAttributeElement, + AttributeSourceContainer container) { + this.pluralAttributeElement = pluralAttributeElement; this.container = container; + + this.keySource = new PluralAttributeKeySourceImpl( pluralAttributeElement.getKey(), container ); + this.elementSource = interpretElementType(); + } + + private PluralAttributeElementSource interpretElementType() { + if ( pluralAttributeElement.getElement() != null ) { + return new BasicPluralAttributeElementSourceImpl( + pluralAttributeElement.getElement(), container.getLocalBindingContext() + ); + } + else if ( pluralAttributeElement.getCompositeElement() != null ) { + return new CompositePluralAttributeElementSourceImpl( + pluralAttributeElement.getCompositeElement(), container.getLocalBindingContext() + ); + } + else if ( pluralAttributeElement.getOneToMany() != null ) { + return new OneToManyPluralAttributeElementSourceImpl( + pluralAttributeElement.getOneToMany(), container.getLocalBindingContext() + ); + } + else if ( pluralAttributeElement.getManyToMany() != null ) { + return new ManyToManyPluralAttributeElementSourceImpl( + pluralAttributeElement.getManyToMany(), container.getLocalBindingContext() + ); + } + else if ( pluralAttributeElement.getManyToAny() != null ) { + throw new NotYetImplementedException( "Support for many-to-any not yet implemented" ); +// return PluralAttributeElementNature.MANY_TO_ANY; + } + else { + throw new MappingException( + "Unexpected collection element type : " + pluralAttributeElement.getName(), + bindingContext().getOrigin() + ); + } + } + + public PluralAttributeElement getPluralAttributeElement() { + return pluralAttributeElement; } protected AttributeSourceContainer container() { @@ -45,8 +100,85 @@ public abstract class AbstractPluralAttributeSourceImpl implements PluralAttribu return container().getLocalBindingContext(); } + @Override + public PluralAttributeKeySource getKeySource() { + return keySource; + } + + @Override + public PluralAttributeElementSource getElementSource() { + return elementSource; + } + + @Override + public String getExplicitSchemaName() { + return pluralAttributeElement.getSchema(); + } + + @Override + public String getExplicitCatalogName() { + return pluralAttributeElement.getCatalog(); + } + + @Override + public String getExplicitCollectionTableName() { + return pluralAttributeElement.getTable(); + } + + @Override + public String getCollectionTableComment() { + return pluralAttributeElement.getComment(); + } + + @Override + public String getCollectionTableCheck() { + return pluralAttributeElement.getCheck(); + } + + @Override + public String getWhere() { + return pluralAttributeElement.getWhere(); + } + + @Override + public String getName() { + return pluralAttributeElement.getName(); + } + @Override public boolean isSingular() { return false; } + + @Override + public String getPropertyAccessorName() { + return pluralAttributeElement.getAccess(); + } + + @Override + public boolean isIncludedInOptimisticLocking() { + return pluralAttributeElement.isOptimisticLock(); + } + + @Override + public boolean isInverse() { + return pluralAttributeElement.isInverse(); + } + + @Override + public Iterable metaAttributes() { + return Helper.buildMetaAttributeSources( pluralAttributeElement.getMeta() ); + } + + @Override + public Iterable getCascadeStyles() { + return Helper.interpretCascadeStyles( pluralAttributeElement.getCascade(), bindingContext() ); + } + + @Override + public FetchMode getFetchMode() { + return pluralAttributeElement.getFetch() == null + ? FetchMode.DEFAULT + : FetchMode.valueOf( pluralAttributeElement.getFetch().value() ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/BagAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/BagAttributeSourceImpl.java index 9c319cb465..cc67abc728 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/BagAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/BagAttributeSourceImpl.java @@ -23,62 +23,18 @@ */ package org.hibernate.metamodel.source.hbm; -import org.hibernate.FetchMode; -import org.hibernate.cfg.NotYetImplementedException; -import org.hibernate.engine.spi.CascadeStyle; -import org.hibernate.metamodel.source.LocalBindingContext; -import org.hibernate.metamodel.source.MappingException; +import org.hibernate.internal.util.StringHelper; import org.hibernate.metamodel.source.binder.AttributeSourceContainer; -import org.hibernate.metamodel.source.binder.MetaAttributeSource; -import org.hibernate.metamodel.source.binder.PluralAttributeElementSource; -import org.hibernate.metamodel.source.binder.PluralAttributeKeySource; +import org.hibernate.metamodel.source.binder.Orderable; import org.hibernate.metamodel.source.binder.PluralAttributeNature; -import org.hibernate.metamodel.source.binder.PluralAttributeSource; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLBagElement; /** * @author Steve Ebersole */ -public class BagAttributeSourceImpl implements PluralAttributeSource { - private final XMLBagElement bagElement; - private final AttributeSourceContainer container; - - // todo : a lot of this could be consolidated with common JAXB interface for collection mappings and moved to a base class - - private final PluralAttributeKeySource keySource; - private final PluralAttributeElementSource elementSource; - +public class BagAttributeSourceImpl extends AbstractPluralAttributeSourceImpl implements Orderable { public BagAttributeSourceImpl(XMLBagElement bagElement, AttributeSourceContainer container) { - this.bagElement = bagElement; - this.container = container; - - this.keySource = new PluralAttributeKeySourceImpl( bagElement.getKey(), container ); - this.elementSource = interpretElementType( bagElement ); - } - - private PluralAttributeElementSource interpretElementType(XMLBagElement bagElement) { - if ( bagElement.getElement() != null ) { - return new BasicPluralAttributeElementSourceImpl( bagElement.getElement(), container.getLocalBindingContext() ); - } - else if ( bagElement.getCompositeElement() != null ) { - return new CompositePluralAttributeElementSourceImpl( bagElement.getCompositeElement(), container.getLocalBindingContext() ); - } - else if ( bagElement.getOneToMany() != null ) { - return new OneToManyPluralAttributeElementSourceImpl( bagElement.getOneToMany(), container.getLocalBindingContext() ); - } - else if ( bagElement.getManyToMany() != null ) { - return new ManyToManyPluralAttributeElementSourceImpl( bagElement.getManyToMany(), container.getLocalBindingContext() ); - } - else if ( bagElement.getManyToAny() != null ) { - throw new NotYetImplementedException( "Support for many-to-any not yet implemented" ); -// return PluralAttributeElementNature.MANY_TO_ANY; - } - else { - throw new MappingException( - "Unexpected collection element type : " + bagElement.getName(), - bindingContext().getOrigin() - ); - } + super( bagElement, container ); } @Override @@ -87,63 +43,17 @@ public class BagAttributeSourceImpl implements PluralAttributeSource { } @Override - public PluralAttributeKeySource getKeySource() { - return keySource; + public XMLBagElement getPluralAttributeElement() { + return (XMLBagElement) super.getPluralAttributeElement(); } @Override - public PluralAttributeElementSource getElementSource() { - return elementSource; + public boolean isOrdered() { + return StringHelper.isNotEmpty( getOrder() ); } @Override - public String getExplicitCollectionTableName() { - return bagElement.getTable(); - } - - private LocalBindingContext bindingContext() { - return container.getLocalBindingContext(); - } - - @Override - public String getName() { - return bagElement.getName(); - } - - @Override - public boolean isSingular() { - return false; - } - - @Override - public String getPropertyAccessorName() { - return bagElement.getAccess(); - } - - @Override - public boolean isIncludedInOptimisticLocking() { - return bagElement.isOptimisticLock(); - } - - @Override - public boolean isInverse() { - return bagElement.isInverse(); - } - - @Override - public Iterable metaAttributes() { - return Helper.buildMetaAttributeSources( bagElement.getMeta() ); - } - - @Override - public Iterable getCascadeStyles() { - return Helper.interpretCascadeStyles( bagElement.getCascade(), bindingContext() ); - } - - @Override - public FetchMode getFetchMode() { - return bagElement.getFetch() == null - ? FetchMode.DEFAULT - : FetchMode.valueOf( bagElement.getFetch().value() ); + public String getOrder() { + return getPluralAttributeElement().getOrderBy(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/Helper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/Helper.java index 1bbb06ec06..1830f54cdb 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/Helper.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/Helper.java @@ -37,6 +37,8 @@ import org.hibernate.internal.util.StringHelper; import org.hibernate.metamodel.binding.CustomSQL; import org.hibernate.metamodel.binding.InheritanceType; import org.hibernate.metamodel.binding.MetaAttribute; +import org.hibernate.metamodel.relational.Identifier; +import org.hibernate.metamodel.relational.Schema; import org.hibernate.metamodel.source.LocalBindingContext; import org.hibernate.metamodel.source.MetaAttributeContext; import org.hibernate.metamodel.source.binder.ExplicitHibernateTypeSource; @@ -233,6 +235,32 @@ public class Helper { return result; } + public static Schema.Name determineDatabaseSchemaName( + String explicitSchemaName, + String explicitCatalogName, + LocalBindingContext bindingContext) { + return new Schema.Name( + resolveIdentifier( + explicitSchemaName, + bindingContext.getMappingDefaults().getSchemaName(), + bindingContext.isGloballyQuotedIdentifiers() + ), + resolveIdentifier( + explicitCatalogName, + bindingContext.getMappingDefaults().getCatalogName(), + bindingContext.isGloballyQuotedIdentifiers() + ) + ); + } + + public static Identifier resolveIdentifier(String explicitName, String defaultName, boolean globalQuoting) { + String name = StringHelper.isNotEmpty( explicitName ) ? explicitName : defaultName; + if ( globalQuoting ) { + name = StringHelper.quote( name ); + } + return Identifier.toIdentifier( name ); + } + public static interface ValueSourcesAdapter { public String getContainingTableName(); public boolean isIncludedInInsertByDefault(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/SetAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/SetAttributeSourceImpl.java index 078b4fc57f..18c6a1e932 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/SetAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/SetAttributeSourceImpl.java @@ -23,150 +23,48 @@ */ package org.hibernate.metamodel.source.hbm; -import org.hibernate.FetchMode; -import org.hibernate.cfg.NotYetImplementedException; -import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.internal.util.StringHelper; -import org.hibernate.metamodel.source.LocalBindingContext; -import org.hibernate.metamodel.source.MappingException; import org.hibernate.metamodel.source.binder.AttributeSourceContainer; -import org.hibernate.metamodel.source.binder.MetaAttributeSource; import org.hibernate.metamodel.source.binder.Orderable; -import org.hibernate.metamodel.source.binder.PluralAttributeElementSource; -import org.hibernate.metamodel.source.binder.PluralAttributeKeySource; import org.hibernate.metamodel.source.binder.PluralAttributeNature; -import org.hibernate.metamodel.source.binder.PluralAttributeSource; import org.hibernate.metamodel.source.binder.Sortable; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLSetElement; /** * @author Steve Ebersole */ -public class SetAttributeSourceImpl implements PluralAttributeSource, Sortable, Orderable { - private XMLSetElement setElement; - private AttributeSourceContainer container; - - // todo : a lot of this could be consolidated with common JAXB interface for collection mappings and moved to a base class - - private final PluralAttributeKeySource keySource; - private final PluralAttributeElementSource elementSource; - +public class SetAttributeSourceImpl extends AbstractPluralAttributeSourceImpl implements Orderable, Sortable { public SetAttributeSourceImpl(XMLSetElement setElement, AttributeSourceContainer container) { - this.setElement = setElement; - this.container = container; - - this.keySource = new PluralAttributeKeySourceImpl( setElement.getKey(), container ); - this.elementSource = interpretElementType( setElement ); + super( setElement, container ); } - private PluralAttributeElementSource interpretElementType(XMLSetElement setElement) { - if ( setElement.getElement() != null ) { - return new BasicPluralAttributeElementSourceImpl( setElement.getElement(), container.getLocalBindingContext() ); - } - else if ( setElement.getCompositeElement() != null ) { - return new CompositePluralAttributeElementSourceImpl( setElement.getCompositeElement(), container.getLocalBindingContext() ); - } - else if ( setElement.getOneToMany() != null ) { - return new OneToManyPluralAttributeElementSourceImpl( setElement.getOneToMany(), container.getLocalBindingContext() ); - } - else if ( setElement.getManyToMany() != null ) { - return new ManyToManyPluralAttributeElementSourceImpl( setElement.getManyToMany(), container.getLocalBindingContext() ); - } - else if ( setElement.getManyToAny() != null ) { - throw new NotYetImplementedException( "Support for many-to-any not yet implemented" ); -// return PluralAttributeElementNature.MANY_TO_ANY; - } - else { - throw new MappingException( - "Unexpected collection element type : " + setElement.getName(), - bindingContext().getOrigin() - ); - } - } - - private LocalBindingContext bindingContext() { - return container.getLocalBindingContext(); + @Override + public XMLSetElement getPluralAttributeElement() { + return (XMLSetElement) super.getPluralAttributeElement(); } @Override public PluralAttributeNature getPluralAttributeNature() { - return PluralAttributeNature.BAG; - } - - @Override - public PluralAttributeKeySource getKeySource() { - return keySource; - } - - @Override - public PluralAttributeElementSource getElementSource() { - return elementSource; - } - - @Override - public String getExplicitCollectionTableName() { - return setElement.getTable(); - } - - @Override - public boolean isInverse() { - return setElement.isInverse(); - } - - @Override - public String getName() { - return setElement.getName(); - } - - @Override - public boolean isSingular() { - return false; - } - - @Override - public String getPropertyAccessorName() { - return setElement.getAccess(); - } - - @Override - public boolean isIncludedInOptimisticLocking() { - return setElement.isOptimisticLock(); - } - - @Override - public Iterable metaAttributes() { - return Helper.buildMetaAttributeSources( setElement.getMeta() ); - } - - @Override - public Iterable getCascadeStyles() { - return Helper.interpretCascadeStyles( setElement.getCascade(), bindingContext() ); - } - - @Override - public FetchMode getFetchMode() { - return setElement.getFetch() == null - ? FetchMode.DEFAULT - : FetchMode.valueOf( setElement.getFetch().value() ); + return PluralAttributeNature.SET; } @Override public boolean isSorted() { - return StringHelper.isNotEmpty( setElement.getSort() ); + return StringHelper.isNotEmpty( getComparatorName() ); } @Override public String getComparatorName() { - return setElement.getSort(); + return getPluralAttributeElement().getSort(); } @Override public boolean isOrdered() { - return StringHelper.isNotEmpty( setElement.getOrderBy() ); + return StringHelper.isNotEmpty( getOrder() ); } @Override public String getOrder() { - return setElement.getOrderBy(); + return getPluralAttributeElement().getOrderBy(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/jaxb/mapping/IdBagPluralAttributeElementAdapter.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/jaxb/mapping/IdBagPluralAttributeElementAdapter.java new file mode 100644 index 0000000000..b7589a0428 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/jaxb/mapping/IdBagPluralAttributeElementAdapter.java @@ -0,0 +1,43 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, 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.source.hbm.jaxb.mapping; + +/** + * Adaptive implementation of the {@link PluralAttributeElement} for {@code } mappings which + * do not support all the configuration available on other collection mappings. + * + * @author Steve Ebersole + */ +public abstract class IdBagPluralAttributeElementAdapter implements PluralAttributeElement { + public XMLOneToManyElement getOneToMany() { + // idbag collections cannot contain 1-m mappings. + return null; + } + + @Override + public boolean isInverse() { + // idbag collections own the association, and are therefore non-inverse + return false; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/jaxb/mapping/PluralAttributeElement.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/jaxb/mapping/PluralAttributeElement.java new file mode 100644 index 0000000000..6eb46ccea1 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/jaxb/mapping/PluralAttributeElement.java @@ -0,0 +1,81 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, 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.source.hbm.jaxb.mapping; + +import java.util.List; + +/** + * Commonality between the various forms of plural attribute (collection) mappings: {@code }, {@code }, etc. + * + * @author Steve Ebersole + */ +public interface PluralAttributeElement extends MetaAttributeContainer { + public String getName(); + public String getAccess(); + + public XMLKeyElement getKey(); + + public XMLElementElement getElement(); + public XMLCompositeElementElement getCompositeElement(); + public XMLOneToManyElement getOneToMany(); + public XMLManyToManyElement getManyToMany(); + public XMLManyToAnyElement getManyToAny(); + + public String getSchema(); + public String getCatalog(); + public String getTable(); + public String getComment(); + public String getCheck(); + public String getSubselect(); + public String getSubselectAttribute(); + public String getWhere(); + + public XMLLoaderElement getLoader(); + public XMLSqlInsertElement getSqlInsert(); + public XMLSqlUpdateElement getSqlUpdate(); + public XMLSqlDeleteElement getSqlDelete(); + public XMLSqlDeleteAllElement getSqlDeleteAll(); + + public List getSynchronize(); + + public XMLCacheElement getCache(); + public List getFilter(); + + public String getCascade(); + public XMLFetchAttributeWithSubselect getFetch(); + public XMLLazyAttributeWithExtra getLazy(); + public XMLOuterJoinAttribute getOuterJoin(); + + public String getBatchSize(); + public boolean isInverse(); + public boolean isMutable(); + public boolean isOptimisticLock(); + + public String getCollectionType(); + public String getPersister(); + +// todo : not available on all. do we need a specific interface for these? +// public String getSort(); +// public String getOrderBy(); +} diff --git a/hibernate-core/src/main/xjb/hbm-mapping-bindings.xjb b/hibernate-core/src/main/xjb/hbm-mapping-bindings.xjb index 21f59a0a2d..274320a2ee 100644 --- a/hibernate-core/src/main/xjb/hbm-mapping-bindings.xjb +++ b/hibernate-core/src/main/xjb/hbm-mapping-bindings.xjb @@ -59,6 +59,23 @@ org.hibernate.metamodel.source.hbm.jaxb.mapping.SingularAttributeSource --> + + org.hibernate.metamodel.source.hbm.jaxb.mapping.PluralAttributeElement + + + org.hibernate.metamodel.source.hbm.jaxb.mapping.PluralAttributeElement + org.hibernate.metamodel.source.hbm.jaxb.mapping.IdBagPluralAttributeElementAdapter + + + org.hibernate.metamodel.source.hbm.jaxb.mapping.PluralAttributeElement + + + org.hibernate.metamodel.source.hbm.jaxb.mapping.PluralAttributeElement + + + org.hibernate.metamodel.source.hbm.jaxb.mapping.PluralAttributeElement + + diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicCollectionBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicCollectionBindingTests.java index c5cf91f295..6f7bf39643 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicCollectionBindingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicCollectionBindingTests.java @@ -79,13 +79,13 @@ public class BasicCollectionBindingTests extends BaseUnitTestCase { assertSame( bagBinding, entityBinding.locateAttributeBinding( "theBag" ) ); assertNotNull( bagBinding.getCollectionTable() ); assertEquals( CollectionElementNature.BASIC, bagBinding.getCollectionElement().getCollectionElementNature() ); - assertEquals( String.class.getName(), bagBinding.getCollectionElement().getHibernateTypeDescriptor().getJavaTypeName() ); + assertEquals( String.class.getName(), ( (BasicCollectionElement) bagBinding.getCollectionElement() ).getHibernateTypeDescriptor().getJavaTypeName() ); PluralAttributeBinding setBinding = metadata.getCollection( EntityWithBasicCollections.class.getName() + ".theSet" ); assertNotNull( setBinding ); assertSame( setBinding, entityBinding.locateAttributeBinding( "theSet" ) ); assertNotNull( setBinding.getCollectionTable() ); assertEquals( CollectionElementNature.BASIC, setBinding.getCollectionElement().getCollectionElementNature() ); - assertEquals( String.class.getName(), setBinding.getCollectionElement().getHibernateTypeDescriptor().getJavaTypeName() ); + assertEquals( String.class.getName(), ( (BasicCollectionElement) setBinding.getCollectionElement() ).getHibernateTypeDescriptor().getJavaTypeName() ); } }