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 <map-key>).

This commit is contained in:
John Verhaeg 2012-04-12 10:57:43 -05:00
parent 5b2cfd3c7c
commit 6dceff93a6
16 changed files with 636 additions and 194 deletions

View File

@ -45,7 +45,8 @@ import org.hibernate.id.factory.IdentifierGeneratorFactory;
import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.internal.HibernateTypeHelper.ReflectedCollectionJavaTypes; 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.AbstractPluralAttributeBinding;
import org.hibernate.metamodel.spi.binding.AttributeBinding; import org.hibernate.metamodel.spi.binding.AttributeBinding;
import org.hibernate.metamodel.spi.binding.AttributeBindingContainer; import org.hibernate.metamodel.spi.binding.AttributeBindingContainer;
@ -63,6 +64,7 @@ import org.hibernate.metamodel.spi.binding.IndexedPluralAttributeBinding;
import org.hibernate.metamodel.spi.binding.InheritanceType; import org.hibernate.metamodel.spi.binding.InheritanceType;
import org.hibernate.metamodel.spi.binding.ListBinding; import org.hibernate.metamodel.spi.binding.ListBinding;
import org.hibernate.metamodel.spi.binding.ManyToOneAttributeBinding; import org.hibernate.metamodel.spi.binding.ManyToOneAttributeBinding;
import org.hibernate.metamodel.spi.binding.MapBinding;
import org.hibernate.metamodel.spi.binding.MetaAttribute; import org.hibernate.metamodel.spi.binding.MetaAttribute;
import org.hibernate.metamodel.spi.binding.PluralAttributeBinding; import org.hibernate.metamodel.spi.binding.PluralAttributeBinding;
import org.hibernate.metamodel.spi.binding.PluralAttributeElementNature; 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;
import org.hibernate.metamodel.spi.source.IdentifierSource.Nature; import org.hibernate.metamodel.spi.source.IdentifierSource.Nature;
import org.hibernate.metamodel.spi.source.InLineViewSource; 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.LocalBindingContext;
import org.hibernate.metamodel.spi.source.MappingDefaults; import org.hibernate.metamodel.spi.source.MappingDefaults;
import org.hibernate.metamodel.spi.source.MappingException; import org.hibernate.metamodel.spi.source.MappingException;
@ -167,6 +170,55 @@ public class Binder {
return new org.hibernate.internal.util.Value< Class< ? >>( deferredInitializer ); 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 MetadataImplementor metadata;
private final IdentifierGeneratorFactory identifierGeneratorFactory; private final IdentifierGeneratorFactory identifierGeneratorFactory;
private final ObjectNameNormalizer nameNormalizer; private final ObjectNameNormalizer nameNormalizer;
@ -176,6 +228,7 @@ public class Binder {
private final HashMap< String, AttributeSource > attributeSourcesByName = new HashMap< String, AttributeSource >(); private final HashMap< String, AttributeSource > attributeSourcesByName = new HashMap< String, AttributeSource >();
private final LinkedList< LocalBindingContext > bindingContexts = new LinkedList< LocalBindingContext >(); private final LinkedList< LocalBindingContext > bindingContexts = new LinkedList< LocalBindingContext >();
private final LinkedList< InheritanceType > inheritanceTypes = new LinkedList< InheritanceType >(); private final LinkedList< InheritanceType > inheritanceTypes = new LinkedList< InheritanceType >();
private final LinkedList< EntityMode > entityModes = new LinkedList< EntityMode >(); private final LinkedList< EntityMode > entityModes = new LinkedList< EntityMode >();
private final HibernateTypeHelper typeHelper; // todo: refactor helper and remove redundant methods in this class private final HibernateTypeHelper typeHelper; // todo: refactor helper and remove redundant methods in this class
@ -210,6 +263,31 @@ public class Binder {
return entityName + "." + attributeName; 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( private AttributeBinding bindAttribute(
final AttributeBindingContainer attributeBindingContainer, final AttributeBindingContainer attributeBindingContainer,
final AttributeSource attributeSource ) { final AttributeSource attributeSource ) {
@ -491,7 +569,7 @@ public class Binder {
if ( attributeBinding.getPluralAttributeElementBinding().getPluralAttributeElementNature() == PluralAttributeElementNature.BASIC ) { if ( attributeBinding.getPluralAttributeElementBinding().getPluralAttributeElementNature() == PluralAttributeElementNature.BASIC ) {
if ( pluralAttributeNature == PluralAttributeNature.SET ) { if ( pluralAttributeNature == PluralAttributeNature.SET ) {
bindBasicElementTablePrimaryKey( attributeBinding ); bindBasicElementTablePrimaryKey( attributeBinding );
} else if ( pluralAttributeNature == PluralAttributeNature.LIST ) { } else if ( pluralAttributeNature == PluralAttributeNature.LIST || pluralAttributeNature == PluralAttributeNature.MAP ) {
bindIndexedTablePrimaryKey( ( IndexedPluralAttributeBinding ) attributeBinding ); bindIndexedTablePrimaryKey( ( IndexedPluralAttributeBinding ) attributeBinding );
} else { } else {
throw new NotYetImplementedException( "Only Sets with basic elements are supported so far." ); 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<SingularAttributeBinding> idAttributeBindings = new ArrayList<SingularAttributeBinding>();
for ( SingularAttributeSource attributeSource : identifierSource.getAttributeSourcesMakingUpIdentifier() ) {
idAttributeBindings.add(
(SingularAttributeBinding) bindAttribute( rootEntityBinding, attributeSource )
);
}
rootEntityBinding.getHierarchyDetails().getEntityIdentifier().bindAsMultipleAttributeIdentifier(
idAttributeBindings,
identifierSource.getLookupIdClass()
);
}
private void bindIndexedTablePrimaryKey( IndexedPluralAttributeBinding attributeBinding ) { private void bindIndexedTablePrimaryKey( IndexedPluralAttributeBinding attributeBinding ) {
final PrimaryKey primaryKey = attributeBinding.getPluralAttributeKeyBinding().getCollectionTable().getPrimaryKey(); final PrimaryKey primaryKey = attributeBinding.getPluralAttributeKeyBinding().getCollectionTable().getPrimaryKey();
final ForeignKey foreignKey = attributeBinding.getPluralAttributeKeyBinding().getForeignKey(); final ForeignKey foreignKey = attributeBinding.getPluralAttributeKeyBinding().getForeignKey();
@ -918,7 +881,7 @@ public class Binder {
private AbstractPluralAttributeBinding bindListAttribute( private AbstractPluralAttributeBinding bindListAttribute(
final AttributeBindingContainer attributeBindingContainer, final AttributeBindingContainer attributeBindingContainer,
final PluralAttributeSource attributeSource, final ListAttributeSource attributeSource,
PluralAttribute attribute ) { PluralAttribute attribute ) {
if ( attribute == null ) { if ( attribute == null ) {
attribute = attributeBindingContainer.getAttributeContainer().createList( attributeSource.getName() ); attribute = attributeBindingContainer.getAttributeContainer().createList( attributeSource.getName() );
@ -931,7 +894,7 @@ public class Binder {
attributeSource.isIncludedInOptimisticLocking(), attributeSource.isIncludedInOptimisticLocking(),
false, false,
createMetaAttributeContext( attributeBindingContainer, attributeSource ), createMetaAttributeContext( attributeBindingContainer, attributeSource ),
((ListAttributeSourceImpl)attributeSource).getIndexSource().base() ); attributeSource.getIndexSource().base() );
} }
private ManyToOneAttributeBinding bindManyToOneAttribute( private ManyToOneAttributeBinding bindManyToOneAttribute(
@ -1010,6 +973,40 @@ public class Binder {
return attributeBinding; 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<SingularAttributeBinding> idAttributeBindings = new ArrayList<SingularAttributeBinding>();
for ( SingularAttributeSource attributeSource : identifierSource.getAttributeSourcesMakingUpIdentifier() ) {
idAttributeBindings.add(
(SingularAttributeBinding) bindAttribute( rootEntityBinding, attributeSource )
);
}
rootEntityBinding.getHierarchyDetails().getEntityIdentifier().bindAsMultipleAttributeIdentifier(
idAttributeBindings,
identifierSource.getLookupIdClass()
);
}
private AbstractPluralAttributeBinding bindPluralAttribute( private AbstractPluralAttributeBinding bindPluralAttribute(
final AttributeBindingContainer attributeBindingContainer, final AttributeBindingContainer attributeBindingContainer,
final PluralAttributeSource attributeSource ) { final PluralAttributeSource attributeSource ) {
@ -1025,8 +1022,11 @@ public class Binder {
attributeBinding = bindSetAttribute( attributeBindingContainer, attributeSource, attribute ); attributeBinding = bindSetAttribute( attributeBindingContainer, attributeSource, attribute );
resolvedType = resolveSetType( ( SetBinding ) attributeBinding ); resolvedType = resolveSetType( ( SetBinding ) attributeBinding );
} else if ( nature == PluralAttributeNature.LIST ) { } else if ( nature == PluralAttributeNature.LIST ) {
attributeBinding = bindListAttribute( attributeBindingContainer, attributeSource, attribute ); attributeBinding = bindListAttribute( attributeBindingContainer, ( ListAttributeSource ) attributeSource, attribute );
resolvedType = resolveListType( ( ListBinding ) attributeBinding ); resolvedType = resolveListType( ( ListBinding ) attributeBinding );
} else if ( nature == PluralAttributeNature.MAP ) {
attributeBinding = bindMapAttribute( attributeBindingContainer, ( MapAttributeSource ) attributeSource, attribute );
resolvedType = resolveMapType( ( MapBinding ) attributeBinding );
} else { } else {
throw new NotYetImplementedException( nature.toString() ); throw new NotYetImplementedException( nature.toString() );
} }
@ -1067,10 +1067,10 @@ public class Binder {
attributeSource.getElementSource().getNature() ) ); attributeSource.getElementSource().getNature() ) );
} }
if (attributeSource instanceof ListAttributeSourceImpl) { if ( attributeSource instanceof IndexedPluralAttributeSource ) {
bindCollectionIndex( bindCollectionIndex(
(IndexedPluralAttributeBinding) attributeBinding, (IndexedPluralAttributeBinding) attributeBinding,
( (ListAttributeSourceImpl) attributeSource ).getIndexSource(), ( (IndexedPluralAttributeSource) attributeSource ).getIndexSource(),
defaultCollectionIndexJavaTypeName( reflectedCollectionJavaTypes ) ); defaultCollectionIndexJavaTypeName( reflectedCollectionJavaTypes ) );
} }
@ -1134,6 +1134,29 @@ public class Binder {
null ); 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( private SingularAttributeBinding bindSingularAttribute(
final AttributeBindingContainer attributeBindingContainer, final AttributeBindingContainer attributeBindingContainer,
final SingularAttributeSource attributeSource ) { final SingularAttributeSource 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 ) { private Type resolveSetType( SetBinding setBinding ) {
if ( setBinding.getHibernateTypeDescriptor().getExplicitTypeName() != null ) { if ( setBinding.getHibernateTypeDescriptor().getExplicitTypeName() != null ) {
return resolveCustomCollectionType( setBinding ); return resolveCustomCollectionType( setBinding );

View File

@ -177,14 +177,18 @@ public abstract class AbstractEntitySourceImpl
); );
} }
else if ( JaxbListElement.class.isInstance( attributeElement ) ) { else if ( JaxbListElement.class.isInstance( attributeElement ) ) {
return new ListAttributeSourceImpl( return new ListAttributeSource(
sourceMappingDocument(), sourceMappingDocument(),
JaxbListElement.class.cast( attributeElement ), JaxbListElement.class.cast( attributeElement ),
this this
); );
} }
else if ( JaxbMapElement.class.isInstance( attributeElement ) ) { else if ( JaxbMapElement.class.isInstance( attributeElement ) ) {
// todo : implement return new MapAttributeSource(
sourceMappingDocument(),
JaxbMapElement.class.cast( attributeElement ),
this
);
} }
throw new UnexpectedAttributeSourceTypeException( throw new UnexpectedAttributeSourceTypeException(

View File

@ -30,7 +30,6 @@ import java.util.Map;
import org.hibernate.internal.jaxb.mapping.hbm.JaxbColumnElement; import org.hibernate.internal.jaxb.mapping.hbm.JaxbColumnElement;
import org.hibernate.internal.jaxb.mapping.hbm.JaxbIndexElement; import org.hibernate.internal.jaxb.mapping.hbm.JaxbIndexElement;
import org.hibernate.internal.jaxb.mapping.hbm.JaxbListIndexElement; 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.ExplicitHibernateTypeSource;
import org.hibernate.metamodel.spi.source.PluralAttributeIndexSource; import org.hibernate.metamodel.spi.source.PluralAttributeIndexSource;
import org.hibernate.metamodel.spi.source.RelationalValueSource; 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 List< RelationalValueSource > valueSources;
private final ExplicitHibernateTypeSource typeSource; private final ExplicitHibernateTypeSource typeSource;
private final int base; private final int base;
public PluralAttributeIndexSourceImpl( public ListAttributeIndexSource( MappingDocument mappingDocument, final JaxbListIndexElement indexElement ) {
MappingDocument mappingDocument,
final JaxbListIndexElement indexElement,
final AttributeSourceContainer container ) {
super( mappingDocument ); super( mappingDocument );
valueSources = Helper.buildValueSources( sourceMappingDocument(), new Helper.ValueSourcesAdapter() { valueSources = Helper.buildValueSources( sourceMappingDocument(), new Helper.ValueSourcesAdapter() {
@ -85,7 +81,6 @@ public class PluralAttributeIndexSourceImpl extends AbstractHbmSourceNode implem
return areValuesIncludedInUpdateByDefault(); return areValuesIncludedInUpdateByDefault();
} }
} ); } );
typeSource = new ExplicitHibernateTypeSource() { typeSource = new ExplicitHibernateTypeSource() {
@Override @Override
@ -98,21 +93,14 @@ public class PluralAttributeIndexSourceImpl extends AbstractHbmSourceNode implem
return java.util.Collections.< String, String >emptyMap(); return java.util.Collections.< String, String >emptyMap();
} }
}; };
base = Integer.parseInt( indexElement.getBase() ); base = Integer.parseInt( indexElement.getBase() );
} }
public PluralAttributeIndexSourceImpl( // TODO: What do we do with the length property?
MappingDocument mappingDocument, public ListAttributeIndexSource( MappingDocument mappingDocument, final JaxbIndexElement indexElement ) {
final JaxbIndexElement indexElement,
final AttributeSourceContainer container ) {
super( mappingDocument ); super( mappingDocument );
valueSources = Helper.buildValueSources( sourceMappingDocument(), new Helper.ValueSourcesAdapter() { valueSources = Helper.buildValueSources( sourceMappingDocument(), new Helper.ValueSourcesAdapter() {
List< JaxbColumnElement > columnElements = indexElement.getColumn() == null
? Collections.EMPTY_LIST
: Collections.singletonList( indexElement.getColumn() );
@Override @Override
public String getColumnAttribute() { public String getColumnAttribute() {
return indexElement.getColumnAttribute(); return indexElement.getColumnAttribute();
@ -120,7 +108,7 @@ public class PluralAttributeIndexSourceImpl extends AbstractHbmSourceNode implem
@Override @Override
public List getColumnOrFormulaElements() { public List getColumnOrFormulaElements() {
return columnElements; return indexElement.getColumn();
} }
@Override @Override
@ -143,12 +131,11 @@ public class PluralAttributeIndexSourceImpl extends AbstractHbmSourceNode implem
return areValuesIncludedInUpdateByDefault(); return areValuesIncludedInUpdateByDefault();
} }
} ); } );
typeSource = new ExplicitHibernateTypeSource() { typeSource = new ExplicitHibernateTypeSource() {
@Override @Override
public String getName() { public String getName() {
return "integer"; return indexElement.getType();
} }
@Override @Override
@ -156,7 +143,6 @@ public class PluralAttributeIndexSourceImpl extends AbstractHbmSourceNode implem
return java.util.Collections.< String, String >emptyMap(); return java.util.Collections.< String, String >emptyMap();
} }
}; };
base = 0; base = 0;
} }
@ -190,12 +176,6 @@ public class PluralAttributeIndexSourceImpl extends AbstractHbmSourceNode implem
return false; return false;
} }
/**
* {@inheritDoc}
*
* @see org.hibernate.metamodel.spi.source.PluralAttributeIndexSource#base()
*/
@Override
public int base() { public int base() {
return base; return base;
} }

View File

@ -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.JaxbListElement;
import org.hibernate.internal.jaxb.mapping.hbm.JaxbListIndexElement; import org.hibernate.internal.jaxb.mapping.hbm.JaxbListIndexElement;
import org.hibernate.metamodel.spi.source.AttributeSourceContainer; 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; 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 sourceMappingDocument
* @param listElement * @param listElement
* @param container * @param container
*/ */
public ListAttributeSourceImpl( public ListAttributeSource(
MappingDocument sourceMappingDocument, MappingDocument sourceMappingDocument,
JaxbListElement listElement, JaxbListElement listElement,
AttributeSourceContainer container ) { AttributeSourceContainer container ) {
super( sourceMappingDocument, listElement, container ); super( sourceMappingDocument, listElement, container );
JaxbListIndexElement listIndexElement = listElement.getListIndex(); JaxbListIndexElement listIndexElement = listElement.getListIndex();
if ( listIndexElement == null ) { if ( listIndexElement == null ) {
this.indexSource = new PluralAttributeIndexSourceImpl( sourceMappingDocument(), listElement.getIndex(), container ); this.indexSource = new ListAttributeIndexSource( sourceMappingDocument(), listElement.getIndex() );
} else { } else {
this.indexSource = new PluralAttributeIndexSourceImpl( sourceMappingDocument(), listIndexElement, container ); this.indexSource = new ListAttributeIndexSource( sourceMappingDocument(), listIndexElement );
} }
} }
public PluralAttributeIndexSource getIndexSource() { @Override
public ListAttributeIndexSource getIndexSource() {
return indexSource; return indexSource;
} }

View File

@ -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;
}
}

View File

@ -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(
"<map-key-many-to-many>, <composite-map-key>, <index>, <composite-index>, <index-many-to-many>, and <index-many-to-any>" );
} 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;
}
}

View File

@ -157,7 +157,7 @@ public interface AttributeBindingContainer {
MetaAttributeContext metaAttributeContext); 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 attribute The attribute for which to make a binding.
* @param nature The nature of the collection elements. * @param nature The nature of the collection elements.
@ -181,7 +181,29 @@ public interface AttributeBindingContainer {
int base ); 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 attribute The attribute for which to make a binding.
* @param nature The nature of the collection elements. * @param nature The nature of the collection elements.

View File

@ -260,6 +260,29 @@ public class CompositeAttributeBinding
return binding; 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 @Override
public SetBinding makeSetAttributeBinding( public SetBinding makeSetAttributeBinding(
PluralAttribute attribute, PluralAttribute attribute,

View File

@ -596,6 +596,29 @@ public class EntityBinding implements AttributeBindingContainer {
return binding; 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 @Override
public SetBinding makeSetAttributeBinding( public SetBinding makeSetAttributeBinding(
PluralAttribute attribute, PluralAttribute attribute,

View File

@ -31,8 +31,8 @@ import org.hibernate.metamodel.spi.source.MetaAttributeContext;
*/ */
public class ListBinding extends AbstractPluralAttributeBinding implements IndexedPluralAttributeBinding { public class ListBinding extends AbstractPluralAttributeBinding implements IndexedPluralAttributeBinding {
private PluralAttributeIndexBinding pluralAttributeIndexBinding; private final PluralAttributeIndexBinding pluralAttributeIndexBinding;
private int base; private final int base;
public ListBinding( public ListBinding(
AttributeBindingContainer container, AttributeBindingContainer container,
@ -53,7 +53,7 @@ public class ListBinding extends AbstractPluralAttributeBinding implements Index
includedInOptimisticLocking, includedInOptimisticLocking,
isLazy, isLazy,
metaAttributeContext ); metaAttributeContext );
this.pluralAttributeIndexBinding = new BasicPluralAttributeIndexBinding( this ); pluralAttributeIndexBinding = new BasicPluralAttributeIndexBinding( this );
this.base = base; this.base = base;
} }

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -28,7 +28,5 @@ package org.hibernate.metamodel.spi.source;
*/ */
public interface PluralAttributeIndexSource extends RelationalValueSourceContainer { public interface PluralAttributeIndexSource extends RelationalValueSourceContainer {
int base();
ExplicitHibernateTypeSource explicitHibernateTypeSource(); ExplicitHibernateTypeSource explicitHibernateTypeSource();
} }

View File

@ -70,7 +70,6 @@ import org.hibernate.jdbc.Expectation;
import org.hibernate.jdbc.Expectations; import org.hibernate.jdbc.Expectations;
import org.hibernate.loader.collection.CollectionInitializer; import org.hibernate.loader.collection.CollectionInitializer;
import org.hibernate.mapping.Collection; import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Formula; import org.hibernate.mapping.Formula;
import org.hibernate.mapping.IdentifierCollection; import org.hibernate.mapping.IdentifierCollection;
import org.hibernate.mapping.IndexedCollection; 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.PluralAttributeKeyBinding;
import org.hibernate.metamodel.spi.binding.RelationalValueBinding; import org.hibernate.metamodel.spi.binding.RelationalValueBinding;
import org.hibernate.metamodel.spi.domain.PluralAttributeNature; 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.DerivedValue;
import org.hibernate.metamodel.spi.relational.TableSpecification; import org.hibernate.metamodel.spi.relational.TableSpecification;
import org.hibernate.metamodel.spi.relational.Value; import org.hibernate.metamodel.spi.relational.Value;
@ -312,7 +312,7 @@ public abstract class AbstractCollectionPersister
int k = 0; int k = 0;
while ( iter.hasNext() ) { while ( iter.hasNext() ) {
// NativeSQL: collect key column and auto-aliases // 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 ); keyColumnNames[k] = col.getQuotedName( dialect );
keyColumnAliases[k] = col.getAlias( dialect, collection.getOwner().getRootTable() ); keyColumnAliases[k] = col.getAlias( dialect, collection.getOwner().getRootTable() );
k++; k++;
@ -360,7 +360,7 @@ public abstract class AbstractCollectionPersister
elementFormulas[j] = form.getFormula(); elementFormulas[j] = form.getFormula();
} }
else { else {
Column col = (Column) selectable; org.hibernate.mapping.Column col = (org.hibernate.mapping.Column) selectable;
elementColumnNames[j] = col.getQuotedName( dialect ); elementColumnNames[j] = col.getQuotedName( dialect );
elementColumnWriters[j] = col.getWriteExpr(); elementColumnWriters[j] = col.getWriteExpr();
elementColumnReaders[j] = col.getReadExpr( dialect ); elementColumnReaders[j] = col.getReadExpr( dialect );
@ -409,7 +409,7 @@ public abstract class AbstractCollectionPersister
hasFormula = true; hasFormula = true;
} }
else { else {
Column indexCol = (Column) s; org.hibernate.mapping.Column indexCol = (org.hibernate.mapping.Column) s;
indexColumnNames[i] = indexCol.getQuotedName( dialect ); indexColumnNames[i] = indexCol.getQuotedName( dialect );
indexColumnIsSettable[i] = true; indexColumnIsSettable[i] = true;
} }
@ -442,7 +442,7 @@ public abstract class AbstractCollectionPersister
IdentifierCollection idColl = (IdentifierCollection) collection; IdentifierCollection idColl = (IdentifierCollection) collection;
identifierType = idColl.getIdentifier().getType(); identifierType = idColl.getIdentifier().getType();
iter = idColl.getIdentifier().getColumnIterator(); iter = idColl.getIdentifier().getColumnIterator();
Column col = (Column) iter.next(); org.hibernate.mapping.Column col = (org.hibernate.mapping.Column) iter.next();
identifierColumnName = col.getQuotedName( dialect ); identifierColumnName = col.getQuotedName( dialect );
identifierColumnAlias = col.getAlias( dialect ); identifierColumnAlias = col.getAlias( dialect );
// unquotedIdentifierColumnName = identifierColumnAlias; // unquotedIdentifierColumnName = identifierColumnAlias;
@ -711,7 +711,7 @@ public abstract class AbstractCollectionPersister
keyColumnNames = new String[keySpan]; keyColumnNames = new String[keySpan];
keyColumnAliases = new String[keySpan]; keyColumnAliases = new String[keySpan];
int k = 0; 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 // NativeSQL: collect key column and auto-aliases
keyColumnNames[k] = keyColumn.getColumnName().encloseInQuotesIfQuoted( dialect ); keyColumnNames[k] = keyColumn.getColumnName().encloseInQuotesIfQuoted( dialect );
// TODO: does the owner root table need to be in alias? // TODO: does the owner root table need to be in alias?
@ -765,7 +765,7 @@ public abstract class AbstractCollectionPersister
elementFormulas[j] = form.getExpression(); elementFormulas[j] = form.getExpression();
} }
else { 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 ); elementColumnNames[j] = col.getColumnName().encloseInQuotesIfQuoted( dialect );
elementColumnWriters[j] = col.getWriteFragment() == null ? "?" : col.getWriteFragment(); elementColumnWriters[j] = col.getWriteFragment() == null ? "?" : col.getWriteFragment();
elementColumnReaders[j] = col.getReadFragment() == null ? elementColumnReaders[j] = col.getReadFragment() == null ?
@ -803,12 +803,23 @@ public abstract class AbstractCollectionPersister
PluralAttributeIndexBinding indexBinding = indexedBinding.getPluralAttributeIndexBinding(); PluralAttributeIndexBinding indexBinding = indexedBinding.getPluralAttributeIndexBinding();
indexType = indexBinding.getHibernateTypeDescriptor().getResolvedTypeMapping(); indexType = indexBinding.getHibernateTypeDescriptor().getResolvedTypeMapping();
baseIndex = indexBinding instanceof ListBinding ? ( ( ListBinding ) indexBinding ).base() : 0; baseIndex = indexBinding instanceof ListBinding ? ( ( ListBinding ) indexBinding ).base() : 0;
Column column = (Column) indexBinding.getIndexRelationalValue(); // TODO: Deal with multiple columns/formulas
indexColumnNames = new String[] { column.getQuotedName( dialect ) }; indexColumnAliases = new String[ 1 ];
indexColumnAliases = new String[] { column.getAlias( dialect ) }; indexColumnNames = new String[ 1 ];
indexFormulaTemplates = new String[1]; indexColumnIsSettable = new boolean[ 1 ];
indexFormulas = new String[1]; indexFormulaTemplates = new String[ 1 ];
indexColumnIsSettable = new boolean[] { true }; 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 { } else {
indexColumnIsSettable = null; indexColumnIsSettable = null;
indexFormulaTemplates = null; indexFormulaTemplates = null;

View File

@ -32,6 +32,12 @@
<element column="list_stuff" type="string"/> <element column="list_stuff" type="string"/>
</list> </list>
<map name="theMap">
<key column="pid"/>
<map-key column="map_key" type="string"/>
<element column="map_value" type="string"/>
</map>
</class> </class>
</hibernate-mapping> </hibernate-mapping>

View File

@ -25,8 +25,10 @@ package org.hibernate.metamodel.spi.binding;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.persistence.ElementCollection; import javax.persistence.ElementCollection;
@ -41,15 +43,16 @@ import javax.persistence.Id;
public class EntityWithBasicCollections { public class EntityWithBasicCollections {
private Long id; private Long id;
private String name; private String name;
private Collection<String> theBag = new ArrayList<String>(); private Collection< String > theBag = new ArrayList< String >();
private Set<String> theSet = new HashSet<String>(); private Set< String > theSet = new HashSet< String >();
private Set<Integer> thePropertyRefSet = new HashSet<Integer>(); private Set< Integer > thePropertyRefSet = new HashSet< Integer >();
private List<String> theList = new ArrayList<String>(); private List< String > theList = new ArrayList< String >();
private Map< String, String > theMap = new HashMap< String, String >();
public EntityWithBasicCollections() { public EntityWithBasicCollections() {
} }
public EntityWithBasicCollections(String name) { public EntityWithBasicCollections( String name ) {
this.name = name; this.name = name;
} }
@ -58,7 +61,7 @@ public class EntityWithBasicCollections {
return id; return id;
} }
public void setId(Long id) { public void setId( Long id ) {
this.id = id; this.id = id;
} }
@ -66,43 +69,52 @@ public class EntityWithBasicCollections {
return name; return name;
} }
public void setName(String name) { public void setName( String name ) {
this.name = name; this.name = name;
} }
@ElementCollection @ElementCollection
public Collection<String> getTheBag() { public Collection< String > getTheBag() {
return theBag; return theBag;
} }
public void setTheBag(Collection<String> theBag) { public void setTheBag( Collection< String > theBag ) {
this.theBag = theBag; this.theBag = theBag;
} }
@ElementCollection @ElementCollection
public Set<String> getTheSet() { public Set< String > getTheSet() {
return theSet; return theSet;
} }
public void setTheSet(Set<String> theSet) { public void setTheSet( Set< String > theSet ) {
this.theSet = theSet; this.theSet = theSet;
} }
@ElementCollection @ElementCollection
public Set<Integer> getThePropertyRefSet() { public Set< Integer > getThePropertyRefSet() {
return thePropertyRefSet; return thePropertyRefSet;
} }
public void setThePropertyRefSet(Set<Integer> thePropertyRefSet) { public void setThePropertyRefSet( Set< Integer > thePropertyRefSet ) {
this.thePropertyRefSet = thePropertyRefSet; this.thePropertyRefSet = thePropertyRefSet;
} }
@ElementCollection @ElementCollection
public List<String> getTheList() { public List< String > getTheList() {
return theList; return theList;
} }
public void setTheList(List<String> theList) { public void setTheList( List< String > theList ) {
this.theList = theList; this.theList = theList;
} }
@ElementCollection
public Map< String, String > getTheMap() {
return theMap;
}
public void setTheMap( Map< String, String > theMap ) {
this.theMap = theMap;
}
} }