HHH-7909 : Add support for non-basic map keys

This commit is contained in:
Gail Badner 2013-01-08 11:20:41 -08:00
parent 1f82999520
commit d7246f1da2
11 changed files with 263 additions and 76 deletions

View File

@ -403,11 +403,11 @@ public class Binder {
if(StringHelper.isEmpty( condition )){
FilterDefinition filterDefinition = metadata.getFilterDefinitions().get( filterSource.getName() );
if(filterDefinition == null){
throw bindingContext().makeMappingException( String.format( "Filter[$s] doesn't have a condition", filterSource.getName() ) );
throw bindingContext().makeMappingException( String.format( "Filter[%s] doesn't have a condition", filterSource.getName() ) );
}
condition = filterDefinition.getDefaultFilterCondition();
}
FilterConfiguration filterConfiguration = new FilterConfiguration(
return new FilterConfiguration(
filterSource.getName(),
condition,
filterSource.shouldAutoInjectAliases(),
@ -415,7 +415,6 @@ public class Binder {
filterSource.getAliasToEntityMap(),
entityBinding
);
return filterConfiguration;
}
private void resolveEntityLaziness(
@ -1667,7 +1666,7 @@ public class Binder {
final String defaultIndexJavaTypeName) {
final BasicPluralAttributeIndexBinding indexBinding =
(BasicPluralAttributeIndexBinding) attributeBinding.getPluralAttributeIndexBinding();
indexBinding.setIndexRelationalValue(
indexBinding.setRelationalValueBindings(
bindValues(
attributeBinding.getContainer(),
attributeSource,
@ -1676,13 +1675,15 @@ public class Binder {
attributeBinding.getPluralAttributeElementBinding()
.getNature() != PluralAttributeElementBinding.Nature.ONE_TO_MANY
)
.get( 0 ).getValue()
);
if ( attributeBinding.getPluralAttributeElementBinding()
.getNature() == PluralAttributeElementBinding.Nature.ONE_TO_MANY ) {
if ( Column.class.isInstance( indexBinding.getIndexRelationalValue() ) ) {
for ( RelationalValueBinding relationalValueBinding : indexBinding.getRelationalValueBindings() ) {
if ( Column.class.isInstance( relationalValueBinding.getValue() ) ) {
// TODO: fix this when column nullability is refactored
( (Column) indexBinding.getIndexRelationalValue() ).setNullable( true );
Column column = (Column) relationalValueBinding.getValue();
column.setNullable( true );
}
}
}
// TODO: create a foreign key if non-inverse and the index is an association
@ -1692,10 +1693,12 @@ public class Binder {
attributeSource.explicitHibernateTypeSource(),
defaultIndexJavaTypeName
);
typeHelper.bindJdbcDataType( indexBinding.getHibernateTypeDescriptor().getResolvedTypeMapping(), indexBinding.getIndexRelationalValue() );
typeHelper.bindJdbcDataType(
indexBinding.getHibernateTypeDescriptor().getResolvedTypeMapping(),
indexBinding.getRelationalValueBindings()
);
}
private SingularAttributeBinding determineReferencedAttributeBinding(
final ForeignKeyContributingSource foreignKeyContributingSource,
final EntityBinding referencedEntityBinding) {
@ -2937,12 +2940,12 @@ public class Binder {
for ( final Column foreignKeyColumn : foreignKey.getSourceColumns() ) {
primaryKey.addColumn( foreignKeyColumn );
}
final Value value = indexBinding.getIndexRelationalValue();
if ( value instanceof Column ) {
primaryKey.addColumn( (Column) value );
for ( RelationalValueBinding relationalValueBinding : indexBinding.getRelationalValueBindings() ) {
if ( relationalValueBinding.getValue() instanceof Column ) {
primaryKey.addColumn( (Column) relationalValueBinding.getValue() );
}
}
}
private static void markSuperEntityTableAbstractIfNecessary(
final EntityBinding superEntityBinding) {

View File

@ -175,7 +175,7 @@ public class CompositePluralAttributeElementSourceImpl
MappingDocument sourceMappingDocument,
JaxbNestedCompositeElementElement attributeElement) {
// todo : implement
throw new NotYetImplementedException();
throw new NotYetImplementedException( "Nested composite element is not supported yet.");
}
@Override

View File

@ -23,8 +23,8 @@
*/
package org.hibernate.metamodel.internal.source.hbm;
import org.hibernate.AssertionFailure;
import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.jaxb.spi.hbm.JaxbIndexElement;
import org.hibernate.jaxb.spi.hbm.JaxbMapElement;
import org.hibernate.jaxb.spi.hbm.JaxbMapKeyElement;
import org.hibernate.metamodel.spi.source.AttributeSourceContainer;
@ -39,7 +39,7 @@ public class MapSource extends AbstractPluralAttributeSourceImpl implements Inde
/**
* @param sourceMappingDocument
* @param pluralAttributeElement
* @param mapElement
* @param container
*/
public MapSource(
@ -47,17 +47,29 @@ public class MapSource extends AbstractPluralAttributeSourceImpl implements Inde
JaxbMapElement mapElement,
AttributeSourceContainer container) {
super( sourceMappingDocument, mapElement, container );
JaxbMapKeyElement mapKey = mapElement.getMapKey();
if ( mapKey != null ) {
this.indexSource = new MapKeySourceImpl( sourceMappingDocument, mapKey );
if ( mapElement.getMapKey() != null ) {
this.indexSource = new MapKeySourceImpl( sourceMappingDocument, mapElement.getMapKey() );
}
else if ( mapElement.getIndex() != null ) {
this.indexSource = new MapKeySourceImpl( sourceMappingDocument, mapElement.getIndex() );
}
else if ( mapElement.getCompositeMapKey() != null ) {
throw new NotYetImplementedException( "<composite-map-key> is not supported yet" );
}
else if ( mapElement.getCompositeIndex() != null ) {
throw new NotYetImplementedException( "<composite-index> is not supported yet" );
}
else if ( mapElement.getMapKeyManyToMany() != null ) {
throw new NotYetImplementedException( "<map-key-many-to-many> is not supported yet" );
}
else if ( mapElement.getIndexManyToMany() != null ) {
throw new NotYetImplementedException( "<index-many-to-many> is not supported yet" );
}
else if ( mapElement.getIndexManyToAny() != null ) {
throw new NotYetImplementedException( "<index-many-to-any> is not supported yet" );
}
else {
JaxbIndexElement indexElement = mapElement.getIndex();
if ( indexElement != null ) {
this.indexSource = new MapKeySourceImpl( sourceMappingDocument, indexElement );
}
throw new NotYetImplementedException(
"<map-key-many-to-many>, <composite-map-key>, <index>, <composite-index>, <index-many-to-many>, and <index-many-to-any>" );
throw new AssertionFailure( "No map key found" );
}
}

View File

@ -0,0 +1,56 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2013, 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.IndexedPluralAttribute;
import org.hibernate.metamodel.spi.domain.Type;
/**
* @author Gail Badner
*/
public abstract class AbstractPluralAttributeIndexBinding implements PluralAttributeIndexBinding {
private final IndexedPluralAttributeBinding pluralAttributeBinding;
private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor();
public AbstractPluralAttributeIndexBinding(
IndexedPluralAttributeBinding pluralAttributeBinding) {
this.pluralAttributeBinding = pluralAttributeBinding;
}
@Override
public HibernateTypeDescriptor getHibernateTypeDescriptor() {
return hibernateTypeDescriptor;
}
@Override
public IndexedPluralAttributeBinding getIndexedPluralAttributeBinding() {
return pluralAttributeBinding;
}
@Override
public Type getPluralAttributeIndexType() {
return ( (IndexedPluralAttribute) getIndexedPluralAttributeBinding().getAttribute() ).getIndexType();
}
}

View File

@ -44,7 +44,8 @@ public class ArrayBinding extends AbstractPluralAttributeBinding implements Inde
referencedAttributeBinding, propertyAccessorName,
includedInOptimisticLocking, metaAttributeContext );
pluralAttributeIndexBinding = new BasicPluralAttributeIndexBinding(
this, PluralAttributeIndexBinding.Nature.BASIC );
this
);
this.base = base;
}

View File

@ -23,53 +23,34 @@
*/
package org.hibernate.metamodel.spi.binding;
import java.util.List;
import org.hibernate.metamodel.spi.domain.IndexedPluralAttribute;
import org.hibernate.metamodel.spi.domain.Type;
import org.hibernate.metamodel.spi.relational.Value;
/**
*
*/
public class BasicPluralAttributeIndexBinding implements PluralAttributeIndexBinding {
public class BasicPluralAttributeIndexBinding extends AbstractPluralAttributeIndexBinding {
private final IndexedPluralAttributeBinding pluralAttributeBinding;
private final Nature pluralAttributeIndexNature;
private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor();
private Value value;
private List<RelationalValueBinding> relationalValueBindings;
public BasicPluralAttributeIndexBinding(
IndexedPluralAttributeBinding pluralAttributeBinding,
Nature pluralAttributeIndexNature) {
this.pluralAttributeBinding = pluralAttributeBinding;
this.pluralAttributeIndexNature = pluralAttributeIndexNature;
IndexedPluralAttributeBinding pluralAttributeBinding) {
super( pluralAttributeBinding );
}
@Override
public HibernateTypeDescriptor getHibernateTypeDescriptor() {
return hibernateTypeDescriptor;
public List<RelationalValueBinding> getRelationalValueBindings() {
return relationalValueBindings;
}
@Override
public Value getIndexRelationalValue() {
return value;
}
@Override
public IndexedPluralAttributeBinding getIndexedPluralAttributeBinding() {
return pluralAttributeBinding;
}
public void setIndexRelationalValue( Value value ) {
this.value = value;
}
@Override
public Type getPluralAttributeIndexType() {
return ( (IndexedPluralAttribute) getIndexedPluralAttributeBinding().getAttribute() ).getIndexType();
public void setRelationalValueBindings(List<RelationalValueBinding> relationalValueBindings) {
this.relationalValueBindings = relationalValueBindings;
}
@Override
public Nature getNature() {
return pluralAttributeIndexNature;
return Nature.BASIC;
}
}

View File

@ -0,0 +1,98 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2013, 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 java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.hibernate.metamodel.spi.domain.Aggregate;
import org.hibernate.metamodel.spi.domain.SingularAttribute;
import org.hibernate.metamodel.spi.source.MetaAttributeContext;
/**
* Describes plural attributes of {@link org.hibernate.metamodel.spi.binding.PluralAttributeElementBinding.Nature#AGGREGATE} elements
*
* @author Gail Badner
*/
public class CompositePluralAttributeIndexBinding extends AbstractPluralAttributeIndexBinding {
// TODO: Come up with a more descriptive name for compositeAttributeBindingContainer.
private AbstractCompositeAttributeBindingContainer compositeAttributeBindingContainer;
public CompositePluralAttributeIndexBinding(IndexedPluralAttributeBinding binding) {
super( binding );
}
@Override
public Nature getNature() {
return Nature.AGGREGATE;
}
public CompositeAttributeBindingContainer createCompositeAttributeBindingContainer(
Aggregate aggregate,
MetaAttributeContext metaAttributeContext,
SingularAttribute parentReference
) {
compositeAttributeBindingContainer =
new AbstractCompositeAttributeBindingContainer(
getIndexedPluralAttributeBinding().getContainer().seekEntityBinding(),
aggregate,
getIndexedPluralAttributeBinding().getPluralAttributeKeyBinding().getCollectionTable(),
aggregate.getRoleBaseName(),
metaAttributeContext,
parentReference
) {
final Map<String,AttributeBinding> attributeBindingMap = new LinkedHashMap<String, AttributeBinding>();
@Override
protected boolean isModifiable() {
return true;
}
@Override
protected Map<String, AttributeBinding> attributeBindingMapInternal() {
return attributeBindingMap;
}
@Override
public boolean isAggregated() {
return true;
}
};
return compositeAttributeBindingContainer;
}
public CompositeAttributeBindingContainer getCompositeAttributeBindingContainer() {
return compositeAttributeBindingContainer;
}
@Override
public List<RelationalValueBinding> getRelationalValueBindings() {
final List<RelationalValueBinding> bindings = new ArrayList<RelationalValueBinding>();
compositeAttributeBindingContainer.collectRelationalValueBindings( bindings );
return bindings;
}
}

View File

@ -51,7 +51,7 @@ public class ListBinding extends AbstractPluralAttributeBinding implements Index
propertyAccessorName,
includedInOptimisticLocking,
metaAttributeContext );
pluralAttributeIndexBinding = new BasicPluralAttributeIndexBinding( this, PluralAttributeIndexBinding.Nature.BASIC );
pluralAttributeIndexBinding = new BasicPluralAttributeIndexBinding( this );
this.base = base;
}

View File

@ -23,6 +23,8 @@
*/
package org.hibernate.metamodel.spi.binding;
import org.hibernate.AssertionFailure;
import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.metamodel.spi.domain.PluralAttribute;
import org.hibernate.metamodel.spi.source.MetaAttributeContext;
@ -51,7 +53,7 @@ public class MapBinding extends AbstractPluralAttributeBinding implements Indexe
includedInOptimisticLocking,
metaAttributeContext
);
pluralAttributeIndexBinding = new BasicPluralAttributeIndexBinding( this, pluralAttributeIndexNature );
pluralAttributeIndexBinding = createPluralAttributeIndexBinding( pluralAttributeIndexNature );
}
/**
@ -64,4 +66,27 @@ public class MapBinding extends AbstractPluralAttributeBinding implements Indexe
return pluralAttributeIndexBinding;
}
private PluralAttributeIndexBinding createPluralAttributeIndexBinding(PluralAttributeIndexBinding.Nature nature) {
switch ( nature ) {
case BASIC: {
return new BasicPluralAttributeIndexBinding( this );
}
case AGGREGATE: {
return new CompositePluralAttributeIndexBinding( this );
}
case MANY_TO_MANY: {
throw new NotYetImplementedException(
String.format( "%s index nature is not supported yet.", nature )
);
}
case MANY_TO_ANY: {
throw new NotYetImplementedException(
String.format( "%s index nature is not supported yet.", nature )
);
}
default: {
throw new AssertionFailure( "Unknown collection index nature : " + nature );
}
}
}
}

View File

@ -23,6 +23,8 @@
*/
package org.hibernate.metamodel.spi.binding;
import java.util.List;
import org.hibernate.metamodel.spi.domain.Type;
import org.hibernate.metamodel.spi.relational.Value;
@ -34,7 +36,13 @@ public interface PluralAttributeIndexBinding {
Nature getNature();
Value getIndexRelationalValue();
/**
* Retrieve the relational aspect of the index binding. Essentially describes the
* column(s)/derived value(s) to which the binding maps the indexes.
*
* @return The relational values.
*/
public List<RelationalValueBinding> getRelationalValueBindings();
HibernateTypeDescriptor getHibernateTypeDescriptor();

View File

@ -832,22 +832,25 @@ public abstract class AbstractCollectionPersister
PluralAttributeIndexBinding indexBinding = indexedBinding.getPluralAttributeIndexBinding();
indexType = indexBinding.getHibernateTypeDescriptor().getResolvedTypeMapping();
baseIndex = indexBinding instanceof ListBinding ? ( ( ListBinding ) indexBinding ).base() : 0;
// 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, null );
final java.util.List<RelationalValueBinding> indexRelationalValueBindings = indexBinding.getRelationalValueBindings();
int indexSpan = indexRelationalValueBindings.size();
indexColumnNames = new String[indexSpan];
indexFormulaTemplates = new String[indexSpan];
indexFormulas = new String[indexSpan];
indexColumnIsSettable = new boolean[indexSpan];
indexColumnAliases = new String[indexSpan];
for ( int i = 0 ; i < indexSpan ; i++ ) {
final Value value = indexRelationalValueBindings.get( i ).getValue();
indexColumnAliases[ i ] = value.getAlias( dialect, null );
if ( value instanceof Column ) {
indexColumnIsSettable[ 0 ] = true;
indexColumnIsSettable[ i ] = true;
Column column = ( Column ) value;
indexColumnNames[ 0 ] = column.getColumnName().getText( dialect );
indexColumnNames[ i ] = column.getColumnName().getText( dialect );
} else {
DerivedValue derivedValue = ( DerivedValue ) value;
indexFormulaTemplates[ 0 ] = getTemplateFromString( derivedValue.getExpression(), factory);
indexFormulas[ 0 ] = derivedValue.getExpression();
indexFormulaTemplates[ i ] = getTemplateFromString( derivedValue.getExpression(), factory);
indexFormulas[ i ] = derivedValue.getExpression();
}
}
} else {
indexColumnIsSettable = null;