HHH-7909: Non-basic map keys and index backrefs
This commit is contained in:
parent
029badbba6
commit
bf5fabd64a
|
@ -25,19 +25,39 @@ package org.hibernate.engine.spi;
|
|||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class SyntheticAttributeHelper {
|
||||
public static final String SYNTHETIC_COMPOSITE_ID_ATTRIBUTE_NAME = "_identifierMapper";
|
||||
|
||||
private static final String BACKREF_ATTRIBUTE_NAME_PREFIX = "_";
|
||||
private static final String BACKREF_ATTRIBUTE_NAME_SUFFIX = "BackRef";
|
||||
private static final String INDEX_BACKREF_ATTRIBUTE_NAME_SUFFIX = "IndexBackRef";
|
||||
|
||||
|
||||
public static String createBackRefAttributeName(String pluralAttributeRole) {
|
||||
return createSyntheticAttributeName(
|
||||
pluralAttributeRole,
|
||||
BACKREF_ATTRIBUTE_NAME_PREFIX,
|
||||
BACKREF_ATTRIBUTE_NAME_SUFFIX
|
||||
);
|
||||
}
|
||||
|
||||
public static String createIndexBackRefAttributeName(String pluralAttributeRole) {
|
||||
return createSyntheticAttributeName(
|
||||
pluralAttributeRole,
|
||||
BACKREF_ATTRIBUTE_NAME_PREFIX,
|
||||
INDEX_BACKREF_ATTRIBUTE_NAME_SUFFIX
|
||||
);
|
||||
}
|
||||
|
||||
private static String createSyntheticAttributeName(String attributeRole, String prefix, String suffix) {
|
||||
return new StringBuilder(
|
||||
BACKREF_ATTRIBUTE_NAME_PREFIX.length() + pluralAttributeRole.length() + BACKREF_ATTRIBUTE_NAME_SUFFIX.length() )
|
||||
.append( BACKREF_ATTRIBUTE_NAME_PREFIX )
|
||||
.append( pluralAttributeRole )
|
||||
.append( BACKREF_ATTRIBUTE_NAME_SUFFIX )
|
||||
prefix.length() + attributeRole.length() + suffix.length() )
|
||||
.append( prefix )
|
||||
.append( attributeRole )
|
||||
.append( suffix )
|
||||
.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding;
|
|||
import org.hibernate.metamodel.spi.binding.AttributeBinding;
|
||||
import org.hibernate.metamodel.spi.binding.CompositeAttributeBindingContainer;
|
||||
import org.hibernate.metamodel.spi.binding.CompositePluralAttributeElementBinding;
|
||||
import org.hibernate.metamodel.spi.binding.CompositePluralAttributeIndexBinding;
|
||||
import org.hibernate.metamodel.spi.binding.IndexedPluralAttributeBinding;
|
||||
import org.hibernate.metamodel.spi.binding.MapBinding;
|
||||
import org.hibernate.metamodel.spi.binding.PluralAttributeBinding;
|
||||
|
@ -337,15 +338,13 @@ public class AttributeBuilder {
|
|||
return getEntityAttributeMetaModelType( attributeTypeDescriptor );
|
||||
}
|
||||
case EMBEDDABLE: {
|
||||
// TODO: Need to implement CompositePluralAttributeIndexBinding
|
||||
// final MapBinding mapBinding = (MapBinding) attributeBinding;
|
||||
// final CompositePluralAttributeIndexBinding pluralAttributeIndexBinding =
|
||||
// (CompositePluralAttributeIndexBinding) mapBinding.getPluralAttributeIndexBinding();
|
||||
// return getEmbeddableAttributeMetaModelType(
|
||||
// attributeTypeDescriptor,
|
||||
// pluralAttributeIndexBinding.getCompositeAttributeBindingContainer();
|
||||
//);
|
||||
throw new NotYetImplementedException( "Composite map indexes are not implemented yet." );
|
||||
final MapBinding mapBinding = (MapBinding) attributeBinding;
|
||||
final CompositePluralAttributeIndexBinding pluralAttributeIndexBinding =
|
||||
(CompositePluralAttributeIndexBinding) mapBinding.getPluralAttributeIndexBinding();
|
||||
return getEmbeddableAttributeMetaModelType(
|
||||
attributeTypeDescriptor,
|
||||
pluralAttributeIndexBinding.getCompositeAttributeBindingContainer()
|
||||
);
|
||||
}
|
||||
default: {
|
||||
throw new AssertionFailure( "Unknown type : " + attributeTypeDescriptor.getValueClassification() );
|
||||
|
|
|
@ -31,6 +31,7 @@ import javax.persistence.metamodel.PluralAttribute;
|
|||
|
||||
import org.hibernate.annotations.common.AssertionFailure;
|
||||
import org.hibernate.jpa.metamodel.internal.AbstractManagedType;
|
||||
import org.hibernate.metamodel.spi.binding.IndexedPluralAttributeBinding;
|
||||
import org.hibernate.metamodel.spi.binding.PluralAttributeBinding;
|
||||
|
||||
/**
|
||||
|
@ -111,7 +112,7 @@ public class PluralAttributeMetadataImpl<X,Y,E>
|
|||
this.keyAttributeTypeDescriptor = new AttributeTypeDescriptor() {
|
||||
@Override
|
||||
public org.hibernate.type.Type getHibernateType() {
|
||||
return getAttributeBinding().getPluralAttributeKeyBinding()
|
||||
return ( (IndexedPluralAttributeBinding) getAttributeBinding() ).getPluralAttributeIndexBinding()
|
||||
.getHibernateTypeDescriptor()
|
||||
.getResolvedTypeMapping();
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ import org.hibernate.metamodel.spi.binding.Cascadeable;
|
|||
import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding;
|
||||
import org.hibernate.metamodel.spi.binding.CompositeAttributeBindingContainer;
|
||||
import org.hibernate.metamodel.spi.binding.CompositePluralAttributeElementBinding;
|
||||
import org.hibernate.metamodel.spi.binding.CompositePluralAttributeIndexBinding;
|
||||
import org.hibernate.metamodel.spi.binding.EntityBinding;
|
||||
import org.hibernate.metamodel.spi.binding.EntityDiscriminator;
|
||||
import org.hibernate.metamodel.spi.binding.EntityIdentifier;
|
||||
|
@ -99,6 +100,7 @@ import org.hibernate.metamodel.spi.binding.SingularNonAssociationAttributeBindin
|
|||
import org.hibernate.metamodel.spi.domain.Aggregate;
|
||||
import org.hibernate.metamodel.spi.domain.Attribute;
|
||||
import org.hibernate.metamodel.spi.domain.Entity;
|
||||
import org.hibernate.metamodel.spi.domain.IndexedPluralAttribute;
|
||||
import org.hibernate.metamodel.spi.domain.PluralAttribute;
|
||||
import org.hibernate.metamodel.spi.domain.SingularAttribute;
|
||||
import org.hibernate.metamodel.spi.relational.Column;
|
||||
|
@ -119,6 +121,7 @@ import org.hibernate.metamodel.spi.source.BasicPluralAttributeIndexSource;
|
|||
import org.hibernate.metamodel.spi.source.ColumnSource;
|
||||
import org.hibernate.metamodel.spi.source.ComponentAttributeSource;
|
||||
import org.hibernate.metamodel.spi.source.CompositePluralAttributeElementSource;
|
||||
import org.hibernate.metamodel.spi.source.CompositePluralAttributeIndexSource;
|
||||
import org.hibernate.metamodel.spi.source.ConstraintSource;
|
||||
import org.hibernate.metamodel.spi.source.DerivedValueSource;
|
||||
import org.hibernate.metamodel.spi.source.DiscriminatorSource;
|
||||
|
@ -1555,9 +1558,11 @@ public class Binder {
|
|||
final String defaultElementJavaTypeName) {
|
||||
bindBasicPluralElementRelationalValues( elementSource, elementBinding );
|
||||
typeHelper.bindBasicCollectionElementType( elementBinding, elementSource, defaultElementJavaTypeName );
|
||||
elementBinding.getPluralAttributeBinding().getAttribute().setElementType(
|
||||
bindingContext().makeJavaType( elementBinding.getHibernateTypeDescriptor().getJavaTypeName() )
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private void bindNonAssociationCollectionKey(
|
||||
final AbstractPluralAttributeBinding attributeBinding,
|
||||
final PluralAttributeSource attributeSource) {
|
||||
|
@ -1633,6 +1638,7 @@ public class Binder {
|
|||
);
|
||||
|
||||
bindAttributes( compositeAttributeBindingContainer, elementSource );
|
||||
pluralAttributeBinding.getAttribute().setElementType( aggregate );
|
||||
Type resolvedType = metadata.getTypeResolver().getTypeFactory().component(
|
||||
new ComponentMetamodel( compositeAttributeBindingContainer, false, false )
|
||||
);
|
||||
|
@ -1679,16 +1685,6 @@ public class Binder {
|
|||
.getNature() != PluralAttributeElementBinding.Nature.ONE_TO_MANY
|
||||
)
|
||||
);
|
||||
if ( attributeBinding.getPluralAttributeElementBinding()
|
||||
.getNature() == PluralAttributeElementBinding.Nature.ONE_TO_MANY ) {
|
||||
for ( RelationalValueBinding relationalValueBinding : indexBinding.getRelationalValueBindings() ) {
|
||||
if ( Column.class.isInstance( relationalValueBinding.getValue() ) ) {
|
||||
// TODO: fix this when column nullability is refactored
|
||||
Column column = (Column) relationalValueBinding.getValue();
|
||||
column.setNullable( true );
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: create a foreign key if non-inverse and the index is an association
|
||||
|
||||
typeHelper.bindHibernateTypeDescriptor(
|
||||
|
@ -1700,6 +1696,65 @@ public class Binder {
|
|||
indexBinding.getHibernateTypeDescriptor().getResolvedTypeMapping(),
|
||||
indexBinding.getRelationalValueBindings()
|
||||
);
|
||||
IndexedPluralAttribute indexedPluralAttribute =
|
||||
(IndexedPluralAttribute) indexBinding.getIndexedPluralAttributeBinding().getAttribute();
|
||||
indexedPluralAttribute.setIndexType(
|
||||
bindingContext().makeJavaType( indexBinding.getHibernateTypeDescriptor().getJavaTypeName() )
|
||||
);
|
||||
}
|
||||
|
||||
private void bindCompositeCollectionIndex(
|
||||
final CompositePluralAttributeIndexBinding indexBinding,
|
||||
final CompositePluralAttributeIndexSource indexSource,
|
||||
final String defaultIndexJavaTypeName) {
|
||||
final PluralAttributeBinding pluralAttributeBinding = indexBinding.getIndexedPluralAttributeBinding();
|
||||
ValueHolder<Class<?>> defaultElementJavaClassReference = null;
|
||||
// Create the aggregate type
|
||||
// TODO: aggregateName should be set to elementSource.getPath() (which is currently not implemented)
|
||||
// or Binder should define AttributeBindingContainer paths instead.
|
||||
String aggregateName = pluralAttributeBinding.getAttribute().getRole() + ".index";
|
||||
final Aggregate aggregate;
|
||||
if ( indexSource.getClassName() != null ) {
|
||||
aggregate = new Aggregate(
|
||||
aggregateName,
|
||||
indexSource.getClassName(),
|
||||
indexSource.getClassReference() != null ?
|
||||
indexSource.getClassReference() :
|
||||
bindingContext().makeClassReference( indexSource.getClassName() ),
|
||||
null
|
||||
);
|
||||
}
|
||||
else {
|
||||
defaultElementJavaClassReference = bindingContext().makeClassReference( defaultIndexJavaTypeName );
|
||||
aggregate = new Aggregate(
|
||||
aggregateName,
|
||||
defaultElementJavaClassReference.getValue().getName(),
|
||||
defaultElementJavaClassReference,
|
||||
null
|
||||
);
|
||||
}
|
||||
final CompositeAttributeBindingContainer compositeAttributeBindingContainer =
|
||||
indexBinding.createCompositeAttributeBindingContainer(
|
||||
aggregate,
|
||||
null,
|
||||
null
|
||||
);
|
||||
|
||||
bindAttributes( compositeAttributeBindingContainer, indexSource );
|
||||
Type resolvedType = metadata.getTypeResolver().getTypeFactory().component(
|
||||
new ComponentMetamodel( compositeAttributeBindingContainer, false, false )
|
||||
);
|
||||
// TODO: binding the HibernateTypeDescriptor should be simplified since we know the class name already
|
||||
typeHelper.bindHibernateTypeDescriptor(
|
||||
indexBinding.getHibernateTypeDescriptor(),
|
||||
aggregate.getClassName(),
|
||||
null,
|
||||
defaultElementJavaClassReference == null ? null : defaultElementJavaClassReference.getValue().getName(),
|
||||
resolvedType
|
||||
);
|
||||
IndexedPluralAttribute indexedPluralAttribute =
|
||||
(IndexedPluralAttribute) indexBinding.getIndexedPluralAttributeBinding().getAttribute();
|
||||
indexedPluralAttribute.setIndexType( aggregate );
|
||||
}
|
||||
|
||||
private SingularAttributeBinding determineReferencedAttributeBinding(
|
||||
|
@ -1728,7 +1783,6 @@ public class Binder {
|
|||
referencedEntityBinding.getHierarchyDetails().getEntityIdentifier()
|
||||
);
|
||||
|
||||
|
||||
Type resolvedElementType = metadata.getTypeResolver().getTypeFactory().manyToOne(
|
||||
referencedEntityBinding.getEntity().getName(),
|
||||
null,
|
||||
|
@ -1747,6 +1801,7 @@ public class Binder {
|
|||
);
|
||||
// no need to bind JDBC data types because element is referenced EntityBinding's ID
|
||||
elementBinding.setCascadeStyle( determineCascadeStyle( elementSource.getCascadeStyles() ) );
|
||||
elementBinding.getPluralAttributeBinding().getAttribute().setElementType( referencedEntityBinding.getEntity() );
|
||||
}
|
||||
|
||||
private void bindManyToManyCollectionElement(
|
||||
|
@ -1774,13 +1829,13 @@ public class Binder {
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
typeHelper.bindManyToManyAttributeType(
|
||||
elementBinding,
|
||||
elementSource,
|
||||
referencedEntityBinding,
|
||||
defaultElementJavaTypeName
|
||||
);
|
||||
elementBinding.getPluralAttributeBinding().getAttribute().setElementType( referencedEntityBinding.getEntity() );
|
||||
elementBinding.setCascadeStyle( determineCascadeStyle( elementSource.getCascadeStyles() ) );
|
||||
elementBinding.setManyToManyWhere( elementSource.getWhere() );
|
||||
elementBinding.setManyToManyOrderBy( elementSource.getOrderBy() );
|
||||
|
@ -1882,12 +1937,22 @@ public class Binder {
|
|||
final IndexedPluralAttributeSource attributeSource,
|
||||
final IndexedPluralAttributeBinding attributeBinding,
|
||||
final ReflectedCollectionJavaTypes reflectedCollectionJavaTypes) {
|
||||
final String defaultCollectionIndexJavaTypeName =
|
||||
HibernateTypeHelper.defaultCollectionIndexJavaTypeName( reflectedCollectionJavaTypes );
|
||||
switch ( attributeSource.getIndexSource().getNature() ) {
|
||||
case BASIC: {
|
||||
bindBasicCollectionIndex(
|
||||
attributeBinding,
|
||||
(BasicPluralAttributeIndexSource) attributeSource.getIndexSource(),
|
||||
HibernateTypeHelper.defaultCollectionIndexJavaTypeName( reflectedCollectionJavaTypes )
|
||||
defaultCollectionIndexJavaTypeName
|
||||
);
|
||||
break;
|
||||
}
|
||||
case AGGREGATE: {
|
||||
bindCompositeCollectionIndex(
|
||||
(CompositePluralAttributeIndexBinding) attributeBinding.getPluralAttributeIndexBinding(),
|
||||
(CompositePluralAttributeIndexSource) attributeSource.getIndexSource(),
|
||||
defaultCollectionIndexJavaTypeName
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
@ -1900,6 +1965,16 @@ public class Binder {
|
|||
);
|
||||
}
|
||||
}
|
||||
if ( attributeBinding.getPluralAttributeElementBinding()
|
||||
.getNature() == PluralAttributeElementBinding.Nature.ONE_TO_MANY ) {
|
||||
for ( RelationalValueBinding relationalValueBinding : attributeBinding.getPluralAttributeIndexBinding().getRelationalValueBindings() ) {
|
||||
if ( Column.class.isInstance( relationalValueBinding.getValue() ) ) {
|
||||
// TODO: fix this when column nullability is refactored
|
||||
Column column = (Column) relationalValueBinding.getValue();
|
||||
column.setNullable( true );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void bindPluralAggregateAttribute(
|
||||
|
@ -2258,15 +2333,12 @@ public class Binder {
|
|||
foreignKey.setDeleteRule( keySource.getOnDeleteAction() );
|
||||
keyBinding.setForeignKey( foreignKey );
|
||||
final HibernateTypeDescriptor pluralAttributeKeyTypeDescriptor = keyBinding.getHibernateTypeDescriptor();
|
||||
final HibernateTypeDescriptor referencedTypeDescriptor =
|
||||
keyBinding.getReferencedAttributeBinding().getHibernateTypeDescriptor();
|
||||
pluralAttributeKeyTypeDescriptor.setExplicitTypeName( referencedTypeDescriptor.getExplicitTypeName() );
|
||||
pluralAttributeKeyTypeDescriptor.setJavaTypeName( referencedTypeDescriptor.getJavaTypeName() );
|
||||
// TODO: not sure about the following...
|
||||
pluralAttributeKeyTypeDescriptor.setToOne( referencedTypeDescriptor.isToOne() );
|
||||
pluralAttributeKeyTypeDescriptor.getTypeParameters().putAll( referencedTypeDescriptor.getTypeParameters() );
|
||||
final Type resolvedKeyType = referencedTypeDescriptor.getResolvedTypeMapping();
|
||||
pluralAttributeKeyTypeDescriptor.setResolvedTypeMapping( resolvedKeyType );
|
||||
;
|
||||
pluralAttributeKeyTypeDescriptor.copyFrom(
|
||||
keyBinding.getReferencedAttributeBinding()
|
||||
.getHibernateTypeDescriptor()
|
||||
);
|
||||
final Type resolvedKeyType = pluralAttributeKeyTypeDescriptor.getResolvedTypeMapping();
|
||||
|
||||
Iterator<Column> fkColumnIterator = keyBinding.getForeignKey().getSourceColumns().iterator();
|
||||
if ( resolvedKeyType.isComponentType() ) {
|
||||
|
|
|
@ -66,9 +66,11 @@ import org.hibernate.metamodel.spi.binding.EntityBinding;
|
|||
import org.hibernate.metamodel.spi.binding.FetchProfile;
|
||||
import org.hibernate.metamodel.spi.binding.HibernateTypeDescriptor;
|
||||
import org.hibernate.metamodel.spi.binding.IdGenerator;
|
||||
import org.hibernate.metamodel.spi.binding.IndexedPluralAttributeBinding;
|
||||
import org.hibernate.metamodel.spi.binding.ManyToOneAttributeBinding;
|
||||
import org.hibernate.metamodel.spi.binding.PluralAttributeBinding;
|
||||
import org.hibernate.metamodel.spi.binding.PluralAttributeElementBinding;
|
||||
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.binding.TypeDefinition;
|
||||
|
@ -423,17 +425,28 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
|
|||
referencedEntityBinding.getEntity().createSyntheticSingularAttribute(
|
||||
SyntheticAttributeHelper.createBackRefAttributeName( pluralAttributeBinding.getAttribute().getRole() ) );
|
||||
// Create the back reference attribute binding.
|
||||
BackRefAttributeBinding backRefAttributeBinding =
|
||||
referencedEntityBinding.makeBackRefAttributeBinding( syntheticAttribute, pluralAttributeBinding );
|
||||
final HibernateTypeDescriptor keyTypeDescriptor = keyBinding.getHibernateTypeDescriptor();
|
||||
final HibernateTypeDescriptor hibernateTypeDescriptor = backRefAttributeBinding.getHibernateTypeDescriptor();
|
||||
hibernateTypeDescriptor.setJavaTypeName( keyTypeDescriptor.getJavaTypeName() );
|
||||
hibernateTypeDescriptor.setExplicitTypeName( keyTypeDescriptor.getExplicitTypeName() );
|
||||
hibernateTypeDescriptor.setToOne( keyTypeDescriptor.isToOne() );
|
||||
hibernateTypeDescriptor.getTypeParameters().putAll( keyTypeDescriptor.getTypeParameters() );
|
||||
hibernateTypeDescriptor.setResolvedTypeMapping( keyTypeDescriptor.getResolvedTypeMapping() );
|
||||
BackRefAttributeBinding backRefAttributeBinding = referencedEntityBinding.makeBackRefAttributeBinding(
|
||||
syntheticAttribute, pluralAttributeBinding, false
|
||||
);
|
||||
backRefAttributeBinding.getHibernateTypeDescriptor().copyFrom( keyBinding.getHibernateTypeDescriptor() );
|
||||
backRefAttributeBinding.getAttribute().resolveType(
|
||||
keyBinding.getReferencedAttributeBinding().getAttribute().getSingularAttributeType() );
|
||||
if ( pluralAttributeBinding.hasIndex() ) {
|
||||
SingularAttribute syntheticIndexAttribute =
|
||||
referencedEntityBinding.getEntity().createSyntheticSingularAttribute(
|
||||
SyntheticAttributeHelper.createIndexBackRefAttributeName( pluralAttributeBinding.getAttribute().getRole() ) );
|
||||
BackRefAttributeBinding indexBackRefAttributeBinding = referencedEntityBinding.makeBackRefAttributeBinding(
|
||||
syntheticIndexAttribute, pluralAttributeBinding, true
|
||||
);
|
||||
final PluralAttributeIndexBinding indexBinding =
|
||||
( (IndexedPluralAttributeBinding) pluralAttributeBinding ).getPluralAttributeIndexBinding();
|
||||
indexBackRefAttributeBinding.getHibernateTypeDescriptor().copyFrom(
|
||||
indexBinding.getHibernateTypeDescriptor()
|
||||
);
|
||||
indexBackRefAttributeBinding.getAttribute().resolveType(
|
||||
indexBinding.getPluralAttributeIndexType()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for ( MetadataSourceProcessor metadataSourceProcessor : metadataSourceProcessors ) {
|
||||
|
|
|
@ -142,7 +142,7 @@ public abstract class AbstractComponentAttributeSourceImpl extends AbstractHbmSo
|
|||
}
|
||||
// todo duplicated with org.hibernate.metamodel.internal.source.hbm.AbstractEntitySourceImpl
|
||||
protected AttributeSource buildAttributeSource(JaxbMapElement attributeElement){
|
||||
return new MapSource(
|
||||
return new MapSourceImpl(
|
||||
sourceMappingDocument(),
|
||||
attributeElement,
|
||||
parentContainer
|
||||
|
|
|
@ -274,7 +274,7 @@ public abstract class AbstractEntitySourceImpl
|
|||
List<JaxbMapElement> propertyElements){
|
||||
for ( JaxbMapElement element : propertyElements ) {
|
||||
results.add(
|
||||
new MapSource(
|
||||
new MapSourceImpl(
|
||||
sourceMappingDocument(),
|
||||
element, this
|
||||
)
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* 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.internal.source.hbm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.internal.util.ValueHolder;
|
||||
import org.hibernate.jaxb.spi.hbm.JaxbCompositeIndexElement;
|
||||
import org.hibernate.jaxb.spi.hbm.JaxbCompositeMapKeyElement;
|
||||
import org.hibernate.jaxb.spi.hbm.JaxbKeyManyToOneElement;
|
||||
import org.hibernate.jaxb.spi.hbm.JaxbKeyPropertyElement;
|
||||
import org.hibernate.metamodel.spi.binding.PluralAttributeIndexBinding;
|
||||
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
|
||||
import org.hibernate.metamodel.spi.source.AttributeSource;
|
||||
import org.hibernate.metamodel.spi.source.CompositePluralAttributeIndexSource;
|
||||
import org.hibernate.metamodel.spi.source.LocalBindingContext;
|
||||
import org.hibernate.metamodel.spi.source.RelationalValueSource;
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class CompositePluralAttributeIndexSourceImpl
|
||||
extends AbstractHbmSourceNode
|
||||
implements CompositePluralAttributeIndexSource {
|
||||
|
||||
private final String className;
|
||||
private final List<AttributeSource> attributeSources;
|
||||
|
||||
public CompositePluralAttributeIndexSourceImpl(
|
||||
MappingDocument mappingDocument,
|
||||
JaxbCompositeIndexElement compositeIndexElement) {
|
||||
this(
|
||||
mappingDocument,
|
||||
compositeIndexElement.getClazz(),
|
||||
compositeIndexElement.getKeyProperty(),
|
||||
compositeIndexElement.getKeyManyToOne()
|
||||
);
|
||||
}
|
||||
|
||||
public CompositePluralAttributeIndexSourceImpl(
|
||||
MappingDocument mappingDocument,
|
||||
JaxbCompositeMapKeyElement compositeMapKeyElement) {
|
||||
this(
|
||||
mappingDocument,
|
||||
compositeMapKeyElement.getClazz(),
|
||||
compositeMapKeyElement.getKeyProperty(),
|
||||
compositeMapKeyElement.getKeyManyToOne()
|
||||
);
|
||||
}
|
||||
|
||||
private CompositePluralAttributeIndexSourceImpl(
|
||||
MappingDocument mappingDocument,
|
||||
String className,
|
||||
List<JaxbKeyPropertyElement> keyPropertyElements,
|
||||
List<JaxbKeyManyToOneElement> keyManyToOneElements) {
|
||||
super( mappingDocument );
|
||||
this.className = bindingContext().qualifyClassName( className );
|
||||
this.attributeSources = buildAttributeSources(
|
||||
mappingDocument,
|
||||
keyPropertyElements,
|
||||
keyManyToOneElements
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluralAttributeIndexBinding.Nature getNature() {
|
||||
return PluralAttributeIndexBinding.Nature.AGGREGATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueHolder<Class<?>> getClassReference() {
|
||||
return bindingContext().makeClassReference( className );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
// todo : implementing this requires passing in the collection source and being able to resolve the collection's role
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AttributeSource> attributeSources() {
|
||||
return attributeSources;
|
||||
}
|
||||
|
||||
private static List<AttributeSource> buildAttributeSources(
|
||||
MappingDocument mappingDocument,
|
||||
List<JaxbKeyPropertyElement> keyPropertyElements,
|
||||
List<JaxbKeyManyToOneElement> keyManyToOneElements) {
|
||||
List<AttributeSource> attributeSources = new ArrayList<AttributeSource>();
|
||||
for ( JaxbKeyPropertyElement keyProperty : keyPropertyElements ){
|
||||
attributeSources.add(
|
||||
new KeyAttributeSourceImpl(
|
||||
mappingDocument,
|
||||
keyProperty,
|
||||
SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID
|
||||
)
|
||||
);
|
||||
}
|
||||
for (JaxbKeyManyToOneElement keyManyToOne :keyManyToOneElements ){
|
||||
attributeSources.add(
|
||||
new KeyManyToOneSourceImpl(
|
||||
mappingDocument,
|
||||
keyManyToOne,
|
||||
SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID
|
||||
)
|
||||
);
|
||||
}
|
||||
return attributeSources;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalBindingContext getLocalBindingContext() {
|
||||
return bindingContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationalValueSource> relationalValueSources() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areValuesIncludedInInsertByDefault() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areValuesIncludedInUpdateByDefault() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areValuesNullableByDefault() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -26,23 +26,23 @@ package org.hibernate.metamodel.internal.source.hbm;
|
|||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.cfg.NotYetImplementedException;
|
||||
import org.hibernate.jaxb.spi.hbm.JaxbMapElement;
|
||||
import org.hibernate.jaxb.spi.hbm.JaxbMapKeyElement;
|
||||
import org.hibernate.metamodel.spi.source.AttributeSourceContainer;
|
||||
import org.hibernate.metamodel.spi.source.IndexedPluralAttributeSource;
|
||||
import org.hibernate.metamodel.spi.source.PluralAttributeIndexSource;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class MapSource extends AbstractPluralAttributeSourceImpl implements IndexedPluralAttributeSource {
|
||||
public class MapSourceImpl extends AbstractPluralAttributeSourceImpl implements IndexedPluralAttributeSource {
|
||||
|
||||
private final MapKeySourceImpl indexSource;
|
||||
private final PluralAttributeIndexSource indexSource;
|
||||
|
||||
/**
|
||||
* @param sourceMappingDocument
|
||||
* @param mapElement
|
||||
* @param container
|
||||
*/
|
||||
public MapSource(
|
||||
public MapSourceImpl(
|
||||
MappingDocument sourceMappingDocument,
|
||||
JaxbMapElement mapElement,
|
||||
AttributeSourceContainer container) {
|
||||
|
@ -54,10 +54,10 @@ public class MapSource extends AbstractPluralAttributeSourceImpl implements Inde
|
|||
this.indexSource = new MapKeySourceImpl( sourceMappingDocument, mapElement.getIndex() );
|
||||
}
|
||||
else if ( mapElement.getCompositeMapKey() != null ) {
|
||||
throw new NotYetImplementedException( "<composite-map-key> is not supported yet" );
|
||||
this.indexSource = new CompositePluralAttributeIndexSourceImpl( sourceMappingDocument, mapElement.getCompositeMapKey() );
|
||||
}
|
||||
else if ( mapElement.getCompositeIndex() != null ) {
|
||||
throw new NotYetImplementedException( "<composite-index> is not supported yet" );
|
||||
this.indexSource = new CompositePluralAttributeIndexSourceImpl( sourceMappingDocument, mapElement.getCompositeIndex() );
|
||||
}
|
||||
else if ( mapElement.getMapKeyManyToMany() != null ) {
|
||||
throw new NotYetImplementedException( "<map-key-many-to-many> is not supported yet" );
|
||||
|
@ -74,7 +74,7 @@ public class MapSource extends AbstractPluralAttributeSourceImpl implements Inde
|
|||
}
|
||||
|
||||
@Override
|
||||
public MapKeySourceImpl getIndexSource() {
|
||||
public PluralAttributeIndexSource getIndexSource() {
|
||||
return indexSource;
|
||||
}
|
||||
|
|
@ -35,16 +35,18 @@ import org.hibernate.metamodel.spi.relational.Column;
|
|||
*/
|
||||
public class BackRefAttributeBinding extends BasicAttributeBinding {
|
||||
|
||||
PluralAttributeBinding pluralAttributeBinding;
|
||||
private final PluralAttributeBinding pluralAttributeBinding;
|
||||
private final boolean isIndexBackRef;
|
||||
|
||||
BackRefAttributeBinding(
|
||||
EntityBinding entityBinding,
|
||||
SingularAttribute attribute,
|
||||
PluralAttributeBinding pluralAttributeBinding) {
|
||||
PluralAttributeBinding pluralAttributeBinding,
|
||||
boolean isIndexBackRef) {
|
||||
super(
|
||||
entityBinding,
|
||||
attribute,
|
||||
createRelationalValueBindings( pluralAttributeBinding ),
|
||||
createRelationalValueBindings( pluralAttributeBinding, isIndexBackRef ),
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
|
@ -53,13 +55,25 @@ public class BackRefAttributeBinding extends BasicAttributeBinding {
|
|||
PropertyGeneration.NEVER
|
||||
);
|
||||
this.pluralAttributeBinding = pluralAttributeBinding;
|
||||
this.isIndexBackRef = isIndexBackRef;
|
||||
}
|
||||
|
||||
private static List<RelationalValueBinding> createRelationalValueBindings(PluralAttributeBinding pluralAttributeBinding) {
|
||||
List<RelationalValueBinding> relationalValueBindings = new ArrayList<RelationalValueBinding>( );
|
||||
private static List<RelationalValueBinding> createRelationalValueBindings(
|
||||
PluralAttributeBinding pluralAttributeBinding,
|
||||
boolean isIndexBackRef) {
|
||||
List<RelationalValueBinding> relationalValueBindings;
|
||||
if ( isIndexBackRef ) {
|
||||
PluralAttributeIndexBinding indexBinding =
|
||||
( (IndexedPluralAttributeBinding) pluralAttributeBinding).getPluralAttributeIndexBinding();
|
||||
relationalValueBindings = indexBinding.getRelationalValueBindings();
|
||||
|
||||
}
|
||||
else {
|
||||
relationalValueBindings = new ArrayList<RelationalValueBinding>( );
|
||||
for ( Column column : pluralAttributeBinding.getPluralAttributeKeyBinding().getForeignKey().getSourceColumns() ) {
|
||||
relationalValueBindings.add( new RelationalValueBinding( column, true, false ) );
|
||||
}
|
||||
}
|
||||
return relationalValueBindings;
|
||||
}
|
||||
|
||||
|
@ -81,6 +95,10 @@ public class BackRefAttributeBinding extends BasicAttributeBinding {
|
|||
return true;
|
||||
}
|
||||
|
||||
public boolean isIndexBackRef() {
|
||||
return isIndexBackRef;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDerivedValue() {
|
||||
return false;
|
||||
|
@ -90,4 +108,9 @@ public class BackRefAttributeBinding extends BasicAttributeBinding {
|
|||
public boolean isNullable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncludedInUpdate() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -650,7 +650,9 @@ public class EntityBinding extends AbstractAttributeBindingContainer implements
|
|||
}
|
||||
|
||||
public BackRefAttributeBinding makeBackRefAttributeBinding(
|
||||
SingularAttribute syntheticAttribute, PluralAttributeBinding pluralAttributeBinding) {
|
||||
SingularAttribute syntheticAttribute,
|
||||
PluralAttributeBinding pluralAttributeBinding,
|
||||
boolean isIndexBackRef) {
|
||||
if ( ! syntheticAttribute.isSynthetic() ) {
|
||||
throw new AssertionFailure(
|
||||
"Illegal attempt to create synthetic attribute binding from non-synthetic attribute reference"
|
||||
|
@ -659,7 +661,8 @@ public class EntityBinding extends AbstractAttributeBindingContainer implements
|
|||
final BackRefAttributeBinding binding = new BackRefAttributeBinding(
|
||||
this,
|
||||
syntheticAttribute,
|
||||
pluralAttributeBinding
|
||||
pluralAttributeBinding,
|
||||
isIndexBackRef
|
||||
);
|
||||
|
||||
registerAttributeBinding( binding );
|
||||
|
|
|
@ -81,4 +81,12 @@ public class HibernateTypeDescriptor {
|
|||
setToOne( resolvedTypeMapping.isEntityType() );
|
||||
}
|
||||
}
|
||||
|
||||
public void copyFrom(HibernateTypeDescriptor hibernateTypeDescriptor) {
|
||||
setJavaTypeName( hibernateTypeDescriptor.getJavaTypeName() );
|
||||
setExplicitTypeName( hibernateTypeDescriptor.getExplicitTypeName() );
|
||||
setToOne( hibernateTypeDescriptor.isToOne() );
|
||||
getTypeParameters().putAll( hibernateTypeDescriptor.getTypeParameters() );
|
||||
setResolvedTypeMapping( hibernateTypeDescriptor.getResolvedTypeMapping() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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.source;
|
||||
|
||||
import org.hibernate.internal.util.ValueHolder;
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public interface CompositePluralAttributeIndexSource
|
||||
extends PluralAttributeIndexSource, AttributeSourceContainer {
|
||||
public String getClassName();
|
||||
|
||||
public ValueHolder<Class<?>> getClassReference();
|
||||
}
|
|
@ -126,16 +126,21 @@ public final class PropertyAccessorFactory {
|
|||
* <p/> *
|
||||
* @param entityName The name of the entity owning the backref property.
|
||||
* @param collectionRole The collection role.
|
||||
* @param isIndexBackRef Is this an index backref?
|
||||
* @param mode The entity mode.
|
||||
* @return An appropriate accessor.
|
||||
* @throws MappingException
|
||||
*/
|
||||
public static PropertyAccessor getBackRefPropertyAccessor(String entityName, String collectionRole, EntityMode mode) {
|
||||
public static PropertyAccessor getBackRefPropertyAccessor(
|
||||
String entityName,
|
||||
String collectionRole,
|
||||
boolean isIndexBackRef,
|
||||
EntityMode mode) {
|
||||
if ( null == mode || EntityMode.POJO.equals( mode ) ) {
|
||||
//TODO: this is temporary in that the end result will probably not take a Property reference per-se.
|
||||
return new BackrefPropertyAccessor(
|
||||
collectionRole, entityName
|
||||
);
|
||||
return isIndexBackRef ?
|
||||
new IndexPropertyAccessor( collectionRole, entityName ) :
|
||||
new BackrefPropertyAccessor( collectionRole, entityName );
|
||||
}
|
||||
else if (EntityMode.MAP.equals( mode ) ) {
|
||||
//TODO: this is temporary in that the end result will probably not take a Property reference per-se.
|
||||
|
|
|
@ -467,7 +467,10 @@ public class PropertyFactory {
|
|||
if ( mappingProperty.isBackRef() ) {
|
||||
BackRefAttributeBinding backRefAttributeBinding = (BackRefAttributeBinding) mappingProperty;
|
||||
return PropertyAccessorFactory.getBackRefPropertyAccessor(
|
||||
backRefAttributeBinding.getEntityName(), backRefAttributeBinding.getCollectionRole(), entityMode
|
||||
backRefAttributeBinding.getEntityName(),
|
||||
backRefAttributeBinding.getCollectionRole(),
|
||||
backRefAttributeBinding.isIndexBackRef(),
|
||||
entityMode
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -43,7 +43,6 @@ import static org.junit.Assert.assertTrue;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@FailureExpectedWithNewMetamodel
|
||||
public class BackrefCompositeMapKeyTest extends BaseCoreFunctionalTestCase {
|
||||
@Override
|
||||
public String[] getMappings() {
|
||||
|
|
Loading…
Reference in New Issue