From 6dceff93a6bb953b37797305f046bf9c91e67860 Mon Sep 17 00:00:00 2001 From: John Verhaeg Date: Thu, 12 Apr 2012 10:57:43 -0500 Subject: [PATCH] HHH-6504: Added basic metamodel support for maps (and corrected a few implementation issues with list support). Still need to address remaining types of map key specifications (other than ). --- .../hibernate/metamodel/internal/Binder.java | 282 ++++++++++-------- .../source/hbm/AbstractEntitySourceImpl.java | 8 +- ...mpl.java => ListAttributeIndexSource.java} | 32 +- ...urceImpl.java => ListAttributeSource.java} | 15 +- .../source/hbm/MapAttributeIndexSource.java | 151 ++++++++++ .../source/hbm/MapAttributeSource.java | 78 +++++ .../binding/AttributeBindingContainer.java | 26 +- .../binding/CompositeAttributeBinding.java | 23 ++ .../metamodel/spi/binding/EntityBinding.java | 23 ++ .../metamodel/spi/binding/ListBinding.java | 6 +- .../metamodel/spi/binding/MapBinding.java | 67 +++++ .../source/IndexedPluralAttributeSource.java | 32 ++ .../source/PluralAttributeIndexSource.java | 2 - .../AbstractCollectionPersister.java | 37 ++- .../EntityWithBasicCollections.hbm.xml | 6 + .../binding/EntityWithBasicCollections.java | 42 ++- 16 files changed, 636 insertions(+), 194 deletions(-) rename hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/{PluralAttributeIndexSourceImpl.java => ListAttributeIndexSource.java} (85%) rename hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/{ListAttributeSourceImpl.java => ListAttributeSource.java} (80%) create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/MapAttributeIndexSource.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/MapAttributeSource.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/MapBinding.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/IndexedPluralAttributeSource.java 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 788ae06be3..09e1974c3d 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 @@ -45,7 +45,8 @@ import org.hibernate.id.factory.IdentifierGeneratorFactory; import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.StringHelper; import org.hibernate.metamodel.internal.HibernateTypeHelper.ReflectedCollectionJavaTypes; -import org.hibernate.metamodel.internal.source.hbm.ListAttributeSourceImpl; +import org.hibernate.metamodel.internal.source.hbm.ListAttributeSource; +import org.hibernate.metamodel.internal.source.hbm.MapAttributeSource; import org.hibernate.metamodel.spi.binding.AbstractPluralAttributeBinding; import org.hibernate.metamodel.spi.binding.AttributeBinding; import org.hibernate.metamodel.spi.binding.AttributeBindingContainer; @@ -63,6 +64,7 @@ import org.hibernate.metamodel.spi.binding.IndexedPluralAttributeBinding; import org.hibernate.metamodel.spi.binding.InheritanceType; import org.hibernate.metamodel.spi.binding.ListBinding; import org.hibernate.metamodel.spi.binding.ManyToOneAttributeBinding; +import org.hibernate.metamodel.spi.binding.MapBinding; import org.hibernate.metamodel.spi.binding.MetaAttribute; import org.hibernate.metamodel.spi.binding.PluralAttributeBinding; import org.hibernate.metamodel.spi.binding.PluralAttributeElementNature; @@ -105,6 +107,7 @@ import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource; import org.hibernate.metamodel.spi.source.IdentifierSource; import org.hibernate.metamodel.spi.source.IdentifierSource.Nature; import org.hibernate.metamodel.spi.source.InLineViewSource; +import org.hibernate.metamodel.spi.source.IndexedPluralAttributeSource; import org.hibernate.metamodel.spi.source.LocalBindingContext; import org.hibernate.metamodel.spi.source.MappingDefaults; import org.hibernate.metamodel.spi.source.MappingException; @@ -167,6 +170,55 @@ public class Binder { return new org.hibernate.internal.util.Value< Class< ? >>( deferredInitializer ); } + private static String getIdentifierUnsavedValue(IdentifierSource identifierSource, IdGenerator generator) { + if ( identifierSource == null ) { + throw new IllegalArgumentException( "identifierSource must be non-null." ); + } + if ( generator == null || StringHelper.isEmpty( generator.getStrategy() ) ) { + throw new IllegalArgumentException( "generator must be non-null and its strategy must be non-empty." ); + } + String unsavedValue = null; + if ( identifierSource.getUnsavedValue() != null ) { + unsavedValue = identifierSource.getUnsavedValue(); + } + else if ( "assigned".equals( generator.getStrategy() ) ) { + unsavedValue = "undefined"; + } + else { + switch ( identifierSource.getNature() ) { + case SIMPLE: { + // unsavedValue = null; + break; + } + case COMPOSITE: { + // The generator strategy should be "assigned" and processed above. + throw new IllegalStateException( + String.format( + "Expected generator strategy for composite ID: 'assigned'; instead it is: %s", + generator.getStrategy() + ) + ); + } + case AGGREGATED_COMPOSITE: { + // TODO: if the component only contains 1 attribute (when flattened) + // and it is not an association then null should be returned; + // otherwise "undefined" should be returned. + throw new NotYetImplementedException( + String.format( + "Unsaved value for (%s) identifier not implemented yet.", + identifierSource.getNature() + ) + ); + } + default: { + throw new AssertionFailure( + String.format( "Unexpected identifier nature: %s", identifierSource.getNature() ) + ); + } + } + } + return unsavedValue; + } private final MetadataImplementor metadata; private final IdentifierGeneratorFactory identifierGeneratorFactory; private final ObjectNameNormalizer nameNormalizer; @@ -176,6 +228,7 @@ public class Binder { private final HashMap< String, AttributeSource > attributeSourcesByName = new HashMap< String, AttributeSource >(); private final LinkedList< LocalBindingContext > bindingContexts = new LinkedList< LocalBindingContext >(); private final LinkedList< InheritanceType > inheritanceTypes = new LinkedList< InheritanceType >(); + private final LinkedList< EntityMode > entityModes = new LinkedList< EntityMode >(); private final HibernateTypeHelper typeHelper; // todo: refactor helper and remove redundant methods in this class @@ -210,6 +263,31 @@ public class Binder { return entityName + "." + attributeName; } + private void bindAggregatedCompositeIdentifier( + EntityBinding rootEntityBinding, + AggregatedCompositeIdentifierSource identifierSource) { + // locate the attribute binding + final CompositeAttributeBinding idAttributeBinding = + ( CompositeAttributeBinding ) bindAttribute( rootEntityBinding, identifierSource.getIdentifierAttributeSource() ); + + // Configure ID generator + IdGenerator generator = identifierSource.getIdentifierGeneratorDescriptor(); + if ( generator == null ) { + final Map< String, String > params = new HashMap< String, String >(); + params.put( IdentifierGenerator.ENTITY_NAME, rootEntityBinding.getEntity().getName() ); + generator = new IdGenerator( "default_assign_identity_generator", "assigned", params ); + } + + // determine the unsaved value mapping + final String unsavedValue = getIdentifierUnsavedValue( identifierSource, generator ); + + rootEntityBinding.getHierarchyDetails().getEntityIdentifier().bindAsSingleAttributeIdentifier( + idAttributeBinding, + generator, + unsavedValue + ); + } + private AttributeBinding bindAttribute( final AttributeBindingContainer attributeBindingContainer, final AttributeSource attributeSource ) { @@ -491,7 +569,7 @@ public class Binder { if ( attributeBinding.getPluralAttributeElementBinding().getPluralAttributeElementNature() == PluralAttributeElementNature.BASIC ) { if ( pluralAttributeNature == PluralAttributeNature.SET ) { bindBasicElementTablePrimaryKey( attributeBinding ); - } else if ( pluralAttributeNature == PluralAttributeNature.LIST ) { + } else if ( pluralAttributeNature == PluralAttributeNature.LIST || pluralAttributeNature == PluralAttributeNature.MAP ) { bindIndexedTablePrimaryKey( ( IndexedPluralAttributeBinding ) attributeBinding ); } else { throw new NotYetImplementedException( "Only Sets with basic elements are supported so far." ); @@ -771,121 +849,6 @@ public class Binder { } } - private void bindSimpleIdentifier( final EntityBinding rootEntityBinding, final SimpleIdentifierSource identifierSource ) { - // locate the attribute binding - final BasicAttributeBinding idAttributeBinding = - ( BasicAttributeBinding ) bindAttribute( rootEntityBinding, identifierSource.getIdentifierAttributeSource() ); - - // Configure ID generator - IdGenerator generator = identifierSource.getIdentifierGeneratorDescriptor(); - if ( generator == null ) { - final Map< String, String > params = new HashMap< String, String >(); - params.put( IdentifierGenerator.ENTITY_NAME, rootEntityBinding.getEntity().getName() ); - generator = new IdGenerator( "default_assign_identity_generator", "assigned", params ); - } - - // determine the unsaved value mapping - final String unsavedValue = getIdentifierUnsavedValue( identifierSource, generator ); - - rootEntityBinding.getHierarchyDetails().getEntityIdentifier().bindAsSingleAttributeIdentifier( - idAttributeBinding, - generator, - unsavedValue - ); - } - - private static String getIdentifierUnsavedValue(IdentifierSource identifierSource, IdGenerator generator) { - if ( identifierSource == null ) { - throw new IllegalArgumentException( "identifierSource must be non-null." ); - } - if ( generator == null || StringHelper.isEmpty( generator.getStrategy() ) ) { - throw new IllegalArgumentException( "generator must be non-null and its strategy must be non-empty." ); - } - String unsavedValue = null; - if ( identifierSource.getUnsavedValue() != null ) { - unsavedValue = identifierSource.getUnsavedValue(); - } - else if ( "assigned".equals( generator.getStrategy() ) ) { - unsavedValue = "undefined"; - } - else { - switch ( identifierSource.getNature() ) { - case SIMPLE: { - unsavedValue = null; - break; - } - case COMPOSITE: { - // The generator strategy should be "assigned" and processed above. - throw new IllegalStateException( - String.format( - "Expected generator strategy for composite ID: 'assigned'; instead it is: %s", - generator.getStrategy() - ) - ); - } - case AGGREGATED_COMPOSITE: { - // TODO: if the component only contains 1 attribute (when flattened) - // and it is not an association then null should be returned; - // otherwise "undefined" should be returned. - throw new NotYetImplementedException( - String.format( - "Unsaved value for (%s) identifier not implemented yet.", - identifierSource.getNature() - ) - ); - } - default: { - throw new AssertionFailure( - String.format( "Unexpected identifier nature: %s", identifierSource.getNature() ) - ); - } - } - } - return unsavedValue; - } - - private void bindAggregatedCompositeIdentifier( - EntityBinding rootEntityBinding, - AggregatedCompositeIdentifierSource identifierSource) { - // locate the attribute binding - final CompositeAttributeBinding idAttributeBinding = - ( CompositeAttributeBinding ) bindAttribute( rootEntityBinding, identifierSource.getIdentifierAttributeSource() ); - - // Configure ID generator - IdGenerator generator = identifierSource.getIdentifierGeneratorDescriptor(); - if ( generator == null ) { - final Map< String, String > params = new HashMap< String, String >(); - params.put( IdentifierGenerator.ENTITY_NAME, rootEntityBinding.getEntity().getName() ); - generator = new IdGenerator( "default_assign_identity_generator", "assigned", params ); - } - - // determine the unsaved value mapping - final String unsavedValue = getIdentifierUnsavedValue( identifierSource, generator ); - - rootEntityBinding.getHierarchyDetails().getEntityIdentifier().bindAsSingleAttributeIdentifier( - idAttributeBinding, - generator, - unsavedValue - ); - } - - private void bindNonAggregatedCompositeIdentifier( - EntityBinding rootEntityBinding, - NonAggregatedCompositeIdentifierSource identifierSource) { - // locate the attribute bindings - List idAttributeBindings = new ArrayList(); - for ( SingularAttributeSource attributeSource : identifierSource.getAttributeSourcesMakingUpIdentifier() ) { - idAttributeBindings.add( - (SingularAttributeBinding) bindAttribute( rootEntityBinding, attributeSource ) - ); - } - - rootEntityBinding.getHierarchyDetails().getEntityIdentifier().bindAsMultipleAttributeIdentifier( - idAttributeBindings, - identifierSource.getLookupIdClass() - ); - } - private void bindIndexedTablePrimaryKey( IndexedPluralAttributeBinding attributeBinding ) { final PrimaryKey primaryKey = attributeBinding.getPluralAttributeKeyBinding().getCollectionTable().getPrimaryKey(); final ForeignKey foreignKey = attributeBinding.getPluralAttributeKeyBinding().getForeignKey(); @@ -918,7 +881,7 @@ public class Binder { private AbstractPluralAttributeBinding bindListAttribute( final AttributeBindingContainer attributeBindingContainer, - final PluralAttributeSource attributeSource, + final ListAttributeSource attributeSource, PluralAttribute attribute ) { if ( attribute == null ) { attribute = attributeBindingContainer.getAttributeContainer().createList( attributeSource.getName() ); @@ -931,7 +894,7 @@ public class Binder { attributeSource.isIncludedInOptimisticLocking(), false, createMetaAttributeContext( attributeBindingContainer, attributeSource ), - ((ListAttributeSourceImpl)attributeSource).getIndexSource().base() ); + attributeSource.getIndexSource().base() ); } private ManyToOneAttributeBinding bindManyToOneAttribute( @@ -1010,6 +973,40 @@ public class Binder { return attributeBinding; } + private AbstractPluralAttributeBinding bindMapAttribute( + final AttributeBindingContainer attributeBindingContainer, + final MapAttributeSource attributeSource, + PluralAttribute attribute ) { + if ( attribute == null ) { + attribute = attributeBindingContainer.getAttributeContainer().createMap( attributeSource.getName() ); + } + return attributeBindingContainer.makeMapAttributeBinding( + attribute, + pluralAttributeElementNature( attributeSource ), + pluralAttributeKeyBinding( attributeBindingContainer, attributeSource ), + propertyAccessorName( attributeSource ), + attributeSource.isIncludedInOptimisticLocking(), + false, + createMetaAttributeContext( attributeBindingContainer, attributeSource ) ); + } + + private void bindNonAggregatedCompositeIdentifier( + EntityBinding rootEntityBinding, + NonAggregatedCompositeIdentifierSource identifierSource) { + // locate the attribute bindings + List idAttributeBindings = new ArrayList(); + for ( SingularAttributeSource attributeSource : identifierSource.getAttributeSourcesMakingUpIdentifier() ) { + idAttributeBindings.add( + (SingularAttributeBinding) bindAttribute( rootEntityBinding, attributeSource ) + ); + } + + rootEntityBinding.getHierarchyDetails().getEntityIdentifier().bindAsMultipleAttributeIdentifier( + idAttributeBindings, + identifierSource.getLookupIdClass() + ); + } + private AbstractPluralAttributeBinding bindPluralAttribute( final AttributeBindingContainer attributeBindingContainer, final PluralAttributeSource attributeSource ) { @@ -1025,8 +1022,11 @@ public class Binder { attributeBinding = bindSetAttribute( attributeBindingContainer, attributeSource, attribute ); resolvedType = resolveSetType( ( SetBinding ) attributeBinding ); } else if ( nature == PluralAttributeNature.LIST ) { - attributeBinding = bindListAttribute( attributeBindingContainer, attributeSource, attribute ); + attributeBinding = bindListAttribute( attributeBindingContainer, ( ListAttributeSource ) attributeSource, attribute ); resolvedType = resolveListType( ( ListBinding ) attributeBinding ); + } else if ( nature == PluralAttributeNature.MAP ) { + attributeBinding = bindMapAttribute( attributeBindingContainer, ( MapAttributeSource ) attributeSource, attribute ); + resolvedType = resolveMapType( ( MapBinding ) attributeBinding ); } else { throw new NotYetImplementedException( nature.toString() ); } @@ -1067,10 +1067,10 @@ public class Binder { attributeSource.getElementSource().getNature() ) ); } - if (attributeSource instanceof ListAttributeSourceImpl) { + if ( attributeSource instanceof IndexedPluralAttributeSource ) { bindCollectionIndex( (IndexedPluralAttributeBinding) attributeBinding, - ( (ListAttributeSourceImpl) attributeSource ).getIndexSource(), + ( (IndexedPluralAttributeSource) attributeSource ).getIndexSource(), defaultCollectionIndexJavaTypeName( reflectedCollectionJavaTypes ) ); } @@ -1133,7 +1133,30 @@ public class Binder { createMetaAttributeContext( attributeBindingContainer, attributeSource ), null ); } - + + private void bindSimpleIdentifier( final EntityBinding rootEntityBinding, final SimpleIdentifierSource identifierSource ) { + // locate the attribute binding + final BasicAttributeBinding idAttributeBinding = + ( BasicAttributeBinding ) bindAttribute( rootEntityBinding, identifierSource.getIdentifierAttributeSource() ); + + // Configure ID generator + IdGenerator generator = identifierSource.getIdentifierGeneratorDescriptor(); + if ( generator == null ) { + final Map< String, String > params = new HashMap< String, String >(); + params.put( IdentifierGenerator.ENTITY_NAME, rootEntityBinding.getEntity().getName() ); + generator = new IdGenerator( "default_assign_identity_generator", "assigned", params ); + } + + // determine the unsaved value mapping + final String unsavedValue = getIdentifierUnsavedValue( identifierSource, generator ); + + rootEntityBinding.getHierarchyDetails().getEntityIdentifier().bindAsSingleAttributeIdentifier( + idAttributeBinding, + generator, + unsavedValue + ); + } + private SingularAttributeBinding bindSingularAttribute( final AttributeBindingContainer attributeBindingContainer, final SingularAttributeSource attributeSource ) { @@ -1249,7 +1272,7 @@ public class Binder { versionAttributeSource.getUnsavedValue() == null ? "undefined" : versionAttributeSource.getUnsavedValue() ); } - + private TableSpecification createCollectionTable( final AbstractPluralAttributeBinding pluralAttributeBinding, final PluralAttributeSource attributeSource ) { @@ -1658,6 +1681,17 @@ public class Binder { } } + private Type resolveMapType( MapBinding mapBinding ) { + if ( mapBinding.getHibernateTypeDescriptor().getExplicitTypeName() != null ) { + return resolveCustomCollectionType( mapBinding ); + } else { + return metadata.getTypeResolver().getTypeFactory().map( + mapBinding.getAttribute().getRole(), + mapBinding.getReferencedPropertyName(), + mapBinding.getPluralAttributeElementBinding().getPluralAttributeElementNature() == PluralAttributeElementNature.COMPOSITE ); + } + } + private Type resolveSetType( SetBinding setBinding ) { if ( setBinding.getHibernateTypeDescriptor().getExplicitTypeName() != null ) { return resolveCustomCollectionType( setBinding ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractEntitySourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractEntitySourceImpl.java index a5a946bf40..e90f0c3a40 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractEntitySourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractEntitySourceImpl.java @@ -177,14 +177,18 @@ public abstract class AbstractEntitySourceImpl ); } else if ( JaxbListElement.class.isInstance( attributeElement ) ) { - return new ListAttributeSourceImpl( + return new ListAttributeSource( sourceMappingDocument(), JaxbListElement.class.cast( attributeElement ), this ); } else if ( JaxbMapElement.class.isInstance( attributeElement ) ) { - // todo : implement + return new MapAttributeSource( + sourceMappingDocument(), + JaxbMapElement.class.cast( attributeElement ), + this + ); } throw new UnexpectedAttributeSourceTypeException( diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/PluralAttributeIndexSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ListAttributeIndexSource.java similarity index 85% rename from hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/PluralAttributeIndexSourceImpl.java rename to hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ListAttributeIndexSource.java index 9a9f730cfc..4d0831cfab 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/PluralAttributeIndexSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ListAttributeIndexSource.java @@ -30,7 +30,6 @@ import java.util.Map; import org.hibernate.internal.jaxb.mapping.hbm.JaxbColumnElement; import org.hibernate.internal.jaxb.mapping.hbm.JaxbIndexElement; import org.hibernate.internal.jaxb.mapping.hbm.JaxbListIndexElement; -import org.hibernate.metamodel.spi.source.AttributeSourceContainer; import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource; import org.hibernate.metamodel.spi.source.PluralAttributeIndexSource; import org.hibernate.metamodel.spi.source.RelationalValueSource; @@ -38,16 +37,13 @@ import org.hibernate.metamodel.spi.source.RelationalValueSource; /** * */ -public class PluralAttributeIndexSourceImpl extends AbstractHbmSourceNode implements PluralAttributeIndexSource { +public class ListAttributeIndexSource extends AbstractHbmSourceNode implements PluralAttributeIndexSource { private final List< RelationalValueSource > valueSources; private final ExplicitHibernateTypeSource typeSource; private final int base; - public PluralAttributeIndexSourceImpl( - MappingDocument mappingDocument, - final JaxbListIndexElement indexElement, - final AttributeSourceContainer container ) { + public ListAttributeIndexSource( MappingDocument mappingDocument, final JaxbListIndexElement indexElement ) { super( mappingDocument ); valueSources = Helper.buildValueSources( sourceMappingDocument(), new Helper.ValueSourcesAdapter() { @@ -85,7 +81,6 @@ public class PluralAttributeIndexSourceImpl extends AbstractHbmSourceNode implem return areValuesIncludedInUpdateByDefault(); } } ); - typeSource = new ExplicitHibernateTypeSource() { @Override @@ -98,21 +93,14 @@ public class PluralAttributeIndexSourceImpl extends AbstractHbmSourceNode implem return java.util.Collections.< String, String >emptyMap(); } }; - base = Integer.parseInt( indexElement.getBase() ); } - public PluralAttributeIndexSourceImpl( - MappingDocument mappingDocument, - final JaxbIndexElement indexElement, - final AttributeSourceContainer container ) { + // TODO: What do we do with the length property? + public ListAttributeIndexSource( MappingDocument mappingDocument, final JaxbIndexElement indexElement ) { super( mappingDocument ); valueSources = Helper.buildValueSources( sourceMappingDocument(), new Helper.ValueSourcesAdapter() { - List< JaxbColumnElement > columnElements = indexElement.getColumn() == null - ? Collections.EMPTY_LIST - : Collections.singletonList( indexElement.getColumn() ); - @Override public String getColumnAttribute() { return indexElement.getColumnAttribute(); @@ -120,7 +108,7 @@ public class PluralAttributeIndexSourceImpl extends AbstractHbmSourceNode implem @Override public List getColumnOrFormulaElements() { - return columnElements; + return indexElement.getColumn(); } @Override @@ -143,12 +131,11 @@ public class PluralAttributeIndexSourceImpl extends AbstractHbmSourceNode implem return areValuesIncludedInUpdateByDefault(); } } ); - typeSource = new ExplicitHibernateTypeSource() { @Override public String getName() { - return "integer"; + return indexElement.getType(); } @Override @@ -156,7 +143,6 @@ public class PluralAttributeIndexSourceImpl extends AbstractHbmSourceNode implem return java.util.Collections.< String, String >emptyMap(); } }; - base = 0; } @@ -190,12 +176,6 @@ public class PluralAttributeIndexSourceImpl extends AbstractHbmSourceNode implem return false; } - /** - * {@inheritDoc} - * - * @see org.hibernate.metamodel.spi.source.PluralAttributeIndexSource#base() - */ - @Override public int base() { return base; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ListAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ListAttributeSource.java similarity index 80% rename from hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ListAttributeSourceImpl.java rename to hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ListAttributeSource.java index d29c1f97db..bb822cd6bc 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ListAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ListAttributeSource.java @@ -26,35 +26,36 @@ package org.hibernate.metamodel.internal.source.hbm; import org.hibernate.internal.jaxb.mapping.hbm.JaxbListElement; import org.hibernate.internal.jaxb.mapping.hbm.JaxbListIndexElement; import org.hibernate.metamodel.spi.source.AttributeSourceContainer; -import org.hibernate.metamodel.spi.source.PluralAttributeIndexSource; +import org.hibernate.metamodel.spi.source.IndexedPluralAttributeSource; import org.hibernate.metamodel.spi.source.PluralAttributeNature; /** * */ -public class ListAttributeSourceImpl extends AbstractPluralAttributeSourceImpl { +public class ListAttributeSource extends AbstractPluralAttributeSourceImpl implements IndexedPluralAttributeSource { - private final PluralAttributeIndexSource indexSource; + private final ListAttributeIndexSource indexSource; /** * @param sourceMappingDocument * @param listElement * @param container */ - public ListAttributeSourceImpl( + public ListAttributeSource( MappingDocument sourceMappingDocument, JaxbListElement listElement, AttributeSourceContainer container ) { super( sourceMappingDocument, listElement, container ); JaxbListIndexElement listIndexElement = listElement.getListIndex(); if ( listIndexElement == null ) { - this.indexSource = new PluralAttributeIndexSourceImpl( sourceMappingDocument(), listElement.getIndex(), container ); + this.indexSource = new ListAttributeIndexSource( sourceMappingDocument(), listElement.getIndex() ); } else { - this.indexSource = new PluralAttributeIndexSourceImpl( sourceMappingDocument(), listIndexElement, container ); + this.indexSource = new ListAttributeIndexSource( sourceMappingDocument(), listIndexElement ); } } - public PluralAttributeIndexSource getIndexSource() { + @Override + public ListAttributeIndexSource getIndexSource() { return indexSource; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/MapAttributeIndexSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/MapAttributeIndexSource.java new file mode 100644 index 0000000000..8f74f5cac7 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/MapAttributeIndexSource.java @@ -0,0 +1,151 @@ +/* + * 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.internal.source.hbm; + +import java.util.List; +import java.util.Map; + +import org.hibernate.internal.jaxb.mapping.hbm.JaxbMapElement.JaxbMapKey; +import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource; +import org.hibernate.metamodel.spi.source.PluralAttributeIndexSource; +import org.hibernate.metamodel.spi.source.RelationalValueSource; + +/** + * + */ +public class MapAttributeIndexSource extends AbstractHbmSourceNode implements PluralAttributeIndexSource { + + private final List< RelationalValueSource > valueSources; + private final ExplicitHibernateTypeSource typeSource; + + /** + * @param sourceMappingDocument + */ + // TODO: What do we do with the length property? + public MapAttributeIndexSource( MappingDocument sourceMappingDocument, final JaxbMapKey mapKey ) { + super( sourceMappingDocument ); + valueSources = Helper.buildValueSources( sourceMappingDocument(), new Helper.ValueSourcesAdapter() { + + @Override + public String getColumnAttribute() { + return mapKey.getColumn(); + } + + @Override + public List getColumnOrFormulaElements() { + return mapKey.getColumnOrFormula(); + } + + @Override + public String getContainingTableName() { + return null; + } + + @Override + public String getFormulaAttribute() { + return mapKey.getFormula(); + } + + @Override + public boolean isIncludedInInsertByDefault() { + return areValuesIncludedInInsertByDefault(); + } + + @Override + public boolean isIncludedInUpdateByDefault() { + return areValuesIncludedInUpdateByDefault(); + } + } ); + this.typeSource = new ExplicitHibernateTypeSource() { + + @Override + public String getName() { + if ( mapKey.getTypeAttribute() != null ) { + return mapKey.getTypeAttribute(); + } + if ( mapKey.getType() != null ) { + return mapKey.getType().getName(); + } + return null; + } + + @Override + public Map< String, String > getParameters() { + return mapKey.getType() != null + ? Helper.extractParameters( mapKey.getType().getParam() ) + : java.util.Collections.< String, String >emptyMap(); + } + }; + } + + /** + * {@inheritDoc} + * + * @see org.hibernate.metamodel.spi.source.ColumnBindingDefaults#areValuesIncludedInInsertByDefault() + */ + @Override + public boolean areValuesIncludedInInsertByDefault() { + return true; + } + + /** + * {@inheritDoc} + * + * @see org.hibernate.metamodel.spi.source.ColumnBindingDefaults#areValuesIncludedInUpdateByDefault() + */ + @Override + public boolean areValuesIncludedInUpdateByDefault() { + return true; + } + + /** + * {@inheritDoc} + * + * @see org.hibernate.metamodel.spi.source.ColumnBindingDefaults#areValuesNullableByDefault() + */ + @Override + public boolean areValuesNullableByDefault() { + return false; + } + + /** + * {@inheritDoc} + * + * @see org.hibernate.metamodel.spi.source.PluralAttributeIndexSource#explicitHibernateTypeSource() + */ + @Override + public ExplicitHibernateTypeSource explicitHibernateTypeSource() { + return typeSource; + } + + /** + * {@inheritDoc} + * + * @see org.hibernate.metamodel.spi.source.RelationalValueSourceContainer#relationalValueSources() + */ + @Override + public List< RelationalValueSource > relationalValueSources() { + return valueSources; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/MapAttributeSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/MapAttributeSource.java new file mode 100644 index 0000000000..31c823601a --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/MapAttributeSource.java @@ -0,0 +1,78 @@ +/* + * 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.internal.source.hbm; + +import org.hibernate.cfg.NotYetImplementedException; +import org.hibernate.internal.jaxb.mapping.hbm.JaxbMapElement; +import org.hibernate.internal.jaxb.mapping.hbm.JaxbMapElement.JaxbMapKey; +import org.hibernate.metamodel.spi.source.AttributeSourceContainer; +import org.hibernate.metamodel.spi.source.IndexedPluralAttributeSource; +import org.hibernate.metamodel.spi.source.PluralAttributeNature; + +/** + * + */ +public class MapAttributeSource extends AbstractPluralAttributeSourceImpl implements IndexedPluralAttributeSource { + + private final MapAttributeIndexSource indexSource; + + /** + * @param sourceMappingDocument + * @param pluralAttributeElement + * @param container + */ + public MapAttributeSource( + MappingDocument sourceMappingDocument, + JaxbMapElement mapElement, + AttributeSourceContainer container ) { + super( sourceMappingDocument, mapElement, container ); + JaxbMapKey mapKey = mapElement.getMapKey(); + if ( mapKey == null ) { + throw new NotYetImplementedException( + ", , , , , and " ); + } else { + this.indexSource = new MapAttributeIndexSource( sourceMappingDocument(), mapKey ); + } + } + + @Override + public MapAttributeIndexSource getIndexSource() { + return indexSource; + } + + @Override + public JaxbMapElement getPluralAttributeElement() { + return ( JaxbMapElement ) super.getPluralAttributeElement(); + } + + /** + * {@inheritDoc} + * + * @see org.hibernate.metamodel.spi.source.PluralAttributeSource#getPluralAttributeNature() + */ + @Override + public PluralAttributeNature getPluralAttributeNature() { + return PluralAttributeNature.MAP; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AttributeBindingContainer.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AttributeBindingContainer.java index bb6081ee39..0e576e9215 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AttributeBindingContainer.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AttributeBindingContainer.java @@ -157,7 +157,7 @@ public interface AttributeBindingContainer { MetaAttributeContext metaAttributeContext); /** - * Factory method for bag attribute bindings. + * Factory method for list attribute bindings. * * @param attribute The attribute for which to make a binding. * @param nature The nature of the collection elements. @@ -181,7 +181,29 @@ public interface AttributeBindingContainer { int base ); /** - * Factory method for bag attribute bindings. + * Factory method for map attribute bindings. + * + * @param attribute The attribute for which to make a binding. + * @param nature The nature of the collection elements. + * @param referencedAttributeBinding + * @param propertyAccessorName + * @param includedInOptimisticLocking + * @param lazy + * @param metaAttributeContext + * + * @return The attribute binding instance. + */ + public MapBinding makeMapAttributeBinding( + PluralAttribute attribute, + PluralAttributeElementNature nature, + SingularAttributeBinding referencedAttributeBinding, + String propertyAccessorName, + boolean includedInOptimisticLocking, + boolean lazy, + MetaAttributeContext metaAttributeContext ); + + /** + * Factory method for set attribute bindings. * * @param attribute The attribute for which to make a binding. * @param nature The nature of the collection elements. diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/CompositeAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/CompositeAttributeBinding.java index 303da14a39..62cfbb046a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/CompositeAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/CompositeAttributeBinding.java @@ -260,6 +260,29 @@ public class CompositeAttributeBinding return binding; } + @Override + public MapBinding makeMapAttributeBinding( + PluralAttribute attribute, + PluralAttributeElementNature nature, + SingularAttributeBinding referencedAttributeBinding, + String propertyAccessorName, + boolean includedInOptimisticLocking, + boolean lazy, + MetaAttributeContext metaAttributeContext ) { + Helper.checkPluralAttributeNature( attribute, PluralAttributeNature.MAP ); + final MapBinding binding = new MapBinding( + this, + attribute, + nature, + referencedAttributeBinding, + propertyAccessorName, + includedInOptimisticLocking, + lazy, + metaAttributeContext ); + registerAttributeBinding( attribute.getName(), binding ); + return binding; + } + @Override public SetBinding makeSetAttributeBinding( PluralAttribute attribute, diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/EntityBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/EntityBinding.java index e4912d7f61..2bed305fa7 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/EntityBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/EntityBinding.java @@ -596,6 +596,29 @@ public class EntityBinding implements AttributeBindingContainer { return binding; } + @Override + public MapBinding makeMapAttributeBinding( + PluralAttribute attribute, + PluralAttributeElementNature nature, + SingularAttributeBinding referencedAttributeBinding, + String propertyAccessorName, + boolean includedInOptimisticLocking, + boolean lazy, + MetaAttributeContext metaAttributeContext ) { + Helper.checkPluralAttributeNature( attribute, PluralAttributeNature.MAP ); + final MapBinding binding = new MapBinding( + this, + attribute, + nature, + referencedAttributeBinding, + propertyAccessorName, + includedInOptimisticLocking, + lazy, + metaAttributeContext ); + registerAttributeBinding( attribute.getName(), binding ); + return binding; + } + @Override public SetBinding makeSetAttributeBinding( PluralAttribute attribute, diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/ListBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/ListBinding.java index c7395b42a2..b2da8b1757 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/ListBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/ListBinding.java @@ -31,8 +31,8 @@ import org.hibernate.metamodel.spi.source.MetaAttributeContext; */ public class ListBinding extends AbstractPluralAttributeBinding implements IndexedPluralAttributeBinding { - private PluralAttributeIndexBinding pluralAttributeIndexBinding; - private int base; + private final PluralAttributeIndexBinding pluralAttributeIndexBinding; + private final int base; public ListBinding( AttributeBindingContainer container, @@ -53,7 +53,7 @@ public class ListBinding extends AbstractPluralAttributeBinding implements Index includedInOptimisticLocking, isLazy, metaAttributeContext ); - this.pluralAttributeIndexBinding = new BasicPluralAttributeIndexBinding( this ); + pluralAttributeIndexBinding = new BasicPluralAttributeIndexBinding( this ); this.base = base; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/MapBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/MapBinding.java new file mode 100644 index 0000000000..18dd485a2c --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/MapBinding.java @@ -0,0 +1,67 @@ +/* + * 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.spi.binding; + +import org.hibernate.metamodel.spi.domain.PluralAttribute; +import org.hibernate.metamodel.spi.source.MetaAttributeContext; + +/** + * + */ +public class MapBinding extends AbstractPluralAttributeBinding implements IndexedPluralAttributeBinding { + + private final PluralAttributeIndexBinding pluralAttributeIndexBinding; + + public MapBinding( + AttributeBindingContainer container, + PluralAttribute attribute, + PluralAttributeElementNature pluralAttributeElementNature, + SingularAttributeBinding referencedAttributeBinding, + String propertyAccessorName, + boolean includedInOptimisticLocking, + boolean isLazy, + MetaAttributeContext metaAttributeContext ) { + super( + container, + attribute, + pluralAttributeElementNature, + referencedAttributeBinding, + propertyAccessorName, + includedInOptimisticLocking, + isLazy, + metaAttributeContext ); + pluralAttributeIndexBinding = new BasicPluralAttributeIndexBinding( this ); + } + + /** + * {@inheritDoc} + * + * @see org.hibernate.metamodel.spi.binding.IndexedPluralAttributeBinding#getPluralAttributeIndexBinding() + */ + @Override + public PluralAttributeIndexBinding getPluralAttributeIndexBinding() { + return pluralAttributeIndexBinding; + } + +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/IndexedPluralAttributeSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/IndexedPluralAttributeSource.java new file mode 100644 index 0000000000..2577ac30b1 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/IndexedPluralAttributeSource.java @@ -0,0 +1,32 @@ +/* + * 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.spi.source; + +/** + * + */ +public interface IndexedPluralAttributeSource extends PluralAttributeSource { + + PluralAttributeIndexSource getIndexSource(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/PluralAttributeIndexSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/PluralAttributeIndexSource.java index 60d674b586..2a570240ed 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/PluralAttributeIndexSource.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/PluralAttributeIndexSource.java @@ -28,7 +28,5 @@ package org.hibernate.metamodel.spi.source; */ public interface PluralAttributeIndexSource extends RelationalValueSourceContainer { - int base(); - ExplicitHibernateTypeSource explicitHibernateTypeSource(); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java index 12ac7d22d8..348878ae20 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java @@ -70,7 +70,6 @@ import org.hibernate.jdbc.Expectation; import org.hibernate.jdbc.Expectations; import org.hibernate.loader.collection.CollectionInitializer; import org.hibernate.mapping.Collection; -import org.hibernate.mapping.Column; import org.hibernate.mapping.Formula; import org.hibernate.mapping.IdentifierCollection; import org.hibernate.mapping.IndexedCollection; @@ -87,6 +86,7 @@ import org.hibernate.metamodel.spi.binding.PluralAttributeIndexBinding; import org.hibernate.metamodel.spi.binding.PluralAttributeKeyBinding; import org.hibernate.metamodel.spi.binding.RelationalValueBinding; import org.hibernate.metamodel.spi.domain.PluralAttributeNature; +import org.hibernate.metamodel.spi.relational.Column; import org.hibernate.metamodel.spi.relational.DerivedValue; import org.hibernate.metamodel.spi.relational.TableSpecification; import org.hibernate.metamodel.spi.relational.Value; @@ -312,7 +312,7 @@ public abstract class AbstractCollectionPersister int k = 0; while ( iter.hasNext() ) { // NativeSQL: collect key column and auto-aliases - Column col = ( (Column) iter.next() ); + org.hibernate.mapping.Column col = ( (org.hibernate.mapping.Column) iter.next() ); keyColumnNames[k] = col.getQuotedName( dialect ); keyColumnAliases[k] = col.getAlias( dialect, collection.getOwner().getRootTable() ); k++; @@ -360,7 +360,7 @@ public abstract class AbstractCollectionPersister elementFormulas[j] = form.getFormula(); } else { - Column col = (Column) selectable; + org.hibernate.mapping.Column col = (org.hibernate.mapping.Column) selectable; elementColumnNames[j] = col.getQuotedName( dialect ); elementColumnWriters[j] = col.getWriteExpr(); elementColumnReaders[j] = col.getReadExpr( dialect ); @@ -409,7 +409,7 @@ public abstract class AbstractCollectionPersister hasFormula = true; } else { - Column indexCol = (Column) s; + org.hibernate.mapping.Column indexCol = (org.hibernate.mapping.Column) s; indexColumnNames[i] = indexCol.getQuotedName( dialect ); indexColumnIsSettable[i] = true; } @@ -442,7 +442,7 @@ public abstract class AbstractCollectionPersister IdentifierCollection idColl = (IdentifierCollection) collection; identifierType = idColl.getIdentifier().getType(); iter = idColl.getIdentifier().getColumnIterator(); - Column col = (Column) iter.next(); + org.hibernate.mapping.Column col = (org.hibernate.mapping.Column) iter.next(); identifierColumnName = col.getQuotedName( dialect ); identifierColumnAlias = col.getAlias( dialect ); // unquotedIdentifierColumnName = identifierColumnAlias; @@ -711,7 +711,7 @@ public abstract class AbstractCollectionPersister keyColumnNames = new String[keySpan]; keyColumnAliases = new String[keySpan]; int k = 0; - for ( org.hibernate.metamodel.spi.relational.Column keyColumn : keyBinding.getForeignKey().getSourceColumns() ) { + for ( Column keyColumn : keyBinding.getForeignKey().getSourceColumns() ) { // NativeSQL: collect key column and auto-aliases keyColumnNames[k] = keyColumn.getColumnName().encloseInQuotesIfQuoted( dialect ); // TODO: does the owner root table need to be in alias? @@ -765,7 +765,7 @@ public abstract class AbstractCollectionPersister elementFormulas[j] = form.getExpression(); } else { - org.hibernate.metamodel.spi.relational.Column col = (org.hibernate.metamodel.spi.relational.Column) value; + Column col = (Column) value; elementColumnNames[j] = col.getColumnName().encloseInQuotesIfQuoted( dialect ); elementColumnWriters[j] = col.getWriteFragment() == null ? "?" : col.getWriteFragment(); elementColumnReaders[j] = col.getReadFragment() == null ? @@ -803,12 +803,23 @@ public abstract class AbstractCollectionPersister PluralAttributeIndexBinding indexBinding = indexedBinding.getPluralAttributeIndexBinding(); indexType = indexBinding.getHibernateTypeDescriptor().getResolvedTypeMapping(); baseIndex = indexBinding instanceof ListBinding ? ( ( ListBinding ) indexBinding ).base() : 0; - Column column = (Column) indexBinding.getIndexRelationalValue(); - indexColumnNames = new String[] { column.getQuotedName( dialect ) }; - indexColumnAliases = new String[] { column.getAlias( dialect ) }; - indexFormulaTemplates = new String[1]; - indexFormulas = new String[1]; - indexColumnIsSettable = new boolean[] { true }; + // TODO: Deal with multiple columns/formulas + indexColumnAliases = new String[ 1 ]; + indexColumnNames = new String[ 1 ]; + indexColumnIsSettable = new boolean[ 1 ]; + indexFormulaTemplates = new String[ 1 ]; + indexFormulas = new String[ 1 ]; + Value value = indexBinding.getIndexRelationalValue(); + indexColumnAliases[ 0 ] = value.getAlias( dialect ); + if ( value instanceof Column ) { + indexColumnIsSettable[ 0 ] = true; + Column column = ( Column ) value; + indexColumnNames[ 0 ] = column.getColumnName().encloseInQuotesIfQuoted( dialect ); + } else { + DerivedValue derivedValue = ( DerivedValue ) value; + indexFormulaTemplates[ 0 ] = getTemplateFromString( derivedValue.getExpression(), factory); + indexFormulas[ 0 ] = derivedValue.getExpression(); + } } else { indexColumnIsSettable = null; indexFormulaTemplates = null; diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/spi/binding/EntityWithBasicCollections.hbm.xml b/hibernate-core/src/test/java/org/hibernate/metamodel/spi/binding/EntityWithBasicCollections.hbm.xml index 0676b5ba49..81367b2a45 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/spi/binding/EntityWithBasicCollections.hbm.xml +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/spi/binding/EntityWithBasicCollections.hbm.xml @@ -32,6 +32,12 @@ + + + + + + diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/spi/binding/EntityWithBasicCollections.java b/hibernate-core/src/test/java/org/hibernate/metamodel/spi/binding/EntityWithBasicCollections.java index 859e8afe03..98ccf61916 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/spi/binding/EntityWithBasicCollections.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/spi/binding/EntityWithBasicCollections.java @@ -25,8 +25,10 @@ package org.hibernate.metamodel.spi.binding; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import javax.persistence.ElementCollection; @@ -41,15 +43,16 @@ import javax.persistence.Id; public class EntityWithBasicCollections { private Long id; private String name; - private Collection theBag = new ArrayList(); - private Set theSet = new HashSet(); - private Set thePropertyRefSet = new HashSet(); - private List theList = new ArrayList(); + private Collection< String > theBag = new ArrayList< String >(); + private Set< String > theSet = new HashSet< String >(); + private Set< Integer > thePropertyRefSet = new HashSet< Integer >(); + private List< String > theList = new ArrayList< String >(); + private Map< String, String > theMap = new HashMap< String, String >(); public EntityWithBasicCollections() { } - public EntityWithBasicCollections(String name) { + public EntityWithBasicCollections( String name ) { this.name = name; } @@ -58,7 +61,7 @@ public class EntityWithBasicCollections { return id; } - public void setId(Long id) { + public void setId( Long id ) { this.id = id; } @@ -66,43 +69,52 @@ public class EntityWithBasicCollections { return name; } - public void setName(String name) { + public void setName( String name ) { this.name = name; } @ElementCollection - public Collection getTheBag() { + public Collection< String > getTheBag() { return theBag; } - public void setTheBag(Collection theBag) { + public void setTheBag( Collection< String > theBag ) { this.theBag = theBag; } @ElementCollection - public Set getTheSet() { + public Set< String > getTheSet() { return theSet; } - public void setTheSet(Set theSet) { + public void setTheSet( Set< String > theSet ) { this.theSet = theSet; } @ElementCollection - public Set getThePropertyRefSet() { + public Set< Integer > getThePropertyRefSet() { return thePropertyRefSet; } - public void setThePropertyRefSet(Set thePropertyRefSet) { + public void setThePropertyRefSet( Set< Integer > thePropertyRefSet ) { this.thePropertyRefSet = thePropertyRefSet; } @ElementCollection - public List getTheList() { + public List< String > getTheList() { return theList; } - public void setTheList(List theList) { + public void setTheList( List< String > theList ) { this.theList = theList; } + + @ElementCollection + public Map< String, String > getTheMap() { + return theMap; + } + + public void setTheMap( Map< String, String > theMap ) { + this.theMap = theMap; + } }