HHH-7523 : Add support for key-many-to-one in composite IDs

This commit is contained in:
Gail Badner 2013-01-03 19:44:46 -08:00
parent 34f34cecbe
commit f5e83567c5
22 changed files with 367 additions and 78 deletions

View File

@ -27,6 +27,7 @@ import static org.hibernate.engine.spi.SyntheticAttributeHelper.SYNTHETIC_COMPOS
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
@ -92,6 +93,7 @@ import org.hibernate.metamodel.spi.binding.SetBinding;
import org.hibernate.metamodel.spi.binding.SingularAssociationAttributeBinding; import org.hibernate.metamodel.spi.binding.SingularAssociationAttributeBinding;
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding.NaturalIdMutability; import org.hibernate.metamodel.spi.binding.SingularAttributeBinding.NaturalIdMutability;
import org.hibernate.metamodel.spi.binding.SingularNonAssociationAttributeBinding;
import org.hibernate.metamodel.spi.domain.Aggregate; import org.hibernate.metamodel.spi.domain.Aggregate;
import org.hibernate.metamodel.spi.domain.Attribute; import org.hibernate.metamodel.spi.domain.Attribute;
import org.hibernate.metamodel.spi.domain.Entity; import org.hibernate.metamodel.spi.domain.Entity;
@ -775,11 +777,6 @@ public class Binder {
for ( SingularAttributeSource attributeSource : identifierSource.getAttributeSourcesMakingUpIdentifier() ) { for ( SingularAttributeSource attributeSource : identifierSource.getAttributeSourcesMakingUpIdentifier() ) {
SingularAttributeBinding singularAttributeBinding = SingularAttributeBinding singularAttributeBinding =
bindIdentifierAttribute( rootEntityBinding, attributeSource ); bindIdentifierAttribute( rootEntityBinding, attributeSource );
if ( singularAttributeBinding.isAssociation() ) {
throw new NotYetImplementedException(
"composite IDs containing an association attribute is not implemented yet."
);
}
idAttributeBindings.add( singularAttributeBinding ); idAttributeBindings.add( singularAttributeBinding );
} }
@ -1128,13 +1125,12 @@ public class Binder {
public EntityType resolveEntityType( public EntityType resolveEntityType(
EntityBinding referencedEntityBinding, EntityBinding referencedEntityBinding,
SingularAttributeBinding referencedAttributeBinding) { SingularAttributeBinding referencedAttributeBinding) {
final boolean isRefToPk = final SingularNonAssociationAttributeBinding idAttributeBinding =
referencedEntityBinding referencedEntityBinding.getHierarchyDetails().getEntityIdentifier().getAttributeBinding();
.getHierarchyDetails().getEntityIdentifier().isIdentifierAttributeBinding(
referencedAttributeBinding
);
final String uniqueKeyAttributeName = final String uniqueKeyAttributeName =
isRefToPk ? null : getRelativePathFromEntityName( referencedAttributeBinding ); idAttributeBinding == referencedAttributeBinding ?
null :
getRelativePathFromEntityName( referencedAttributeBinding );
return metadata.getTypeResolver().getTypeFactory().manyToOne( return metadata.getTypeResolver().getTypeFactory().manyToOne(
referencedEntityBinding.getEntity().getName(), referencedEntityBinding.getEntity().getName(),
uniqueKeyAttributeName, uniqueKeyAttributeName,
@ -1183,6 +1179,34 @@ public class Binder {
EntityBinding referencedEntityBinding, EntityBinding referencedEntityBinding,
SingularAttributeBinding referencedAttributeBinding SingularAttributeBinding referencedAttributeBinding
) { ) {
/**
* this is not correct, here, if no @JoinColumn defined, we simply create the FK column only with column calucated
* but what we should do is get all the column info from the referenced column(s), including nullable, size etc.
*/
final TableSpecification table = locateDefaultTableSpecificationForAttribute(
attributeBindingContainer,
attributeSource
);
final List<RelationalValueBinding> relationalValueBindings;
if ( ! attributeSource.relationalValueSources().isEmpty() ) {
relationalValueBindings =
bindValues(
attributeBindingContainer,
attributeSource,
actualAttribute,
table,
attributeSource.getDefaultNamingStrategies(
attributeBindingContainer.seekEntityBinding().getEntity().getName(),
table.getLogicalName().getText(),
referencedAttributeBinding
),
false
);
}
else {
relationalValueBindings = Collections.emptyList();
}
// todo : currently a chicken-egg problem here between creating the attribute binding and binding its FK values... // todo : currently a chicken-egg problem here between creating the attribute binding and binding its FK values...
return attributeBindingContainer.makeOneToOneAttributeBinding( return attributeBindingContainer.makeOneToOneAttributeBinding(
actualAttribute, actualAttribute,
@ -1193,7 +1217,8 @@ public class Binder {
createMetaAttributeContext( attributeBindingContainer, attributeSource ), createMetaAttributeContext( attributeBindingContainer, attributeSource ),
referencedEntityBinding, referencedEntityBinding,
referencedAttributeBinding, referencedAttributeBinding,
attributeSource.getForeignKeyDirection() == ForeignKeyDirection.FROM_PARENT attributeSource.getForeignKeyDirection() == ForeignKeyDirection.FROM_PARENT,
relationalValueBindings
); );
} }
@ -1201,22 +1226,34 @@ public class Binder {
public EntityType resolveEntityType( public EntityType resolveEntityType(
EntityBinding referencedEntityBinding, EntityBinding referencedEntityBinding,
SingularAttributeBinding referencedAttributeBinding) { SingularAttributeBinding referencedAttributeBinding) {
final boolean isRefToPk = final SingularNonAssociationAttributeBinding idAttributeBinding =
referencedEntityBinding referencedEntityBinding.getHierarchyDetails().getEntityIdentifier().getAttributeBinding();
.getHierarchyDetails().getEntityIdentifier().isIdentifierAttributeBinding(
referencedAttributeBinding
);
final String uniqueKeyAttributeName = final String uniqueKeyAttributeName =
isRefToPk ? null : getRelativePathFromEntityName( referencedAttributeBinding ); idAttributeBinding == referencedAttributeBinding ?
return metadata.getTypeResolver().getTypeFactory().oneToOne( null :
referencedEntityBinding.getEntity().getName(), getRelativePathFromEntityName( referencedAttributeBinding );
attributeSource.getForeignKeyDirection(), if ( attributeSource.relationalValueSources().isEmpty() ) {
uniqueKeyAttributeName, return metadata.getTypeResolver().getTypeFactory().oneToOne(
attributeSource.getFetchTiming() != FetchTiming.IMMEDIATE, referencedEntityBinding.getEntity().getName(),
attributeSource.isUnWrapProxy(), attributeSource.getForeignKeyDirection(),
attributeBindingContainer.seekEntityBinding().getEntityName(), uniqueKeyAttributeName,
actualAttribute.getName() attributeSource.getFetchTiming() != FetchTiming.IMMEDIATE,
); attributeSource.isUnWrapProxy(),
attributeBindingContainer.seekEntityBinding().getEntityName(),
actualAttribute.getName()
);
}
else {
return metadata.getTypeResolver().getTypeFactory().specialOneToOne(
referencedEntityBinding.getEntity().getName(),
attributeSource.getForeignKeyDirection(),
uniqueKeyAttributeName,
attributeSource.getFetchTiming() != FetchTiming.IMMEDIATE,
attributeSource.isUnWrapProxy(),
attributeBindingContainer.seekEntityBinding().getEntityName(),
actualAttribute.getName()
);
}
} }
}; };

View File

@ -37,6 +37,7 @@ import org.hibernate.metamodel.spi.relational.Value;
import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource; import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource;
import org.hibernate.metamodel.spi.source.MappingException; import org.hibernate.metamodel.spi.source.MappingException;
import org.hibernate.metamodel.spi.source.ToOneAttributeSource; import org.hibernate.metamodel.spi.source.ToOneAttributeSource;
import org.hibernate.type.ForeignKeyDirection;
/** /**
* @author Gail Badner * @author Gail Badner
@ -84,6 +85,7 @@ public abstract class AbstractToOneAttributeSourceImpl extends AbstractHbmSource
return getFetchTiming() != FetchTiming.IMMEDIATE; return getFetchTiming() != FetchTiming.IMMEDIATE;
} }
protected abstract boolean requiresImmediateFetch();
protected abstract String getFetchSelectionString(); protected abstract String getFetchSelectionString();
protected abstract String getLazySelectionString(); protected abstract String getLazySelectionString();
protected abstract String getOuterJoinSelectionString(); protected abstract String getOuterJoinSelectionString();
@ -99,7 +101,10 @@ public abstract class AbstractToOneAttributeSourceImpl extends AbstractHbmSource
final String lazySelection = getLazySelectionString(); final String lazySelection = getLazySelectionString();
if ( lazySelection == null ) { if ( lazySelection == null ) {
if ( "join".equals( getFetchSelectionString() ) || "true".equals( getOuterJoinSelectionString() ) ) { if ( requiresImmediateFetch() ) {
return FetchTiming.IMMEDIATE;
}
else if ( "join".equals( getFetchSelectionString() ) || "true".equals( getOuterJoinSelectionString() ) ) {
return FetchTiming.IMMEDIATE; return FetchTiming.IMMEDIATE;
} }
else if ( "false".equals( getOuterJoinSelectionString() ) ) { else if ( "false".equals( getOuterJoinSelectionString() ) ) {
@ -136,7 +141,10 @@ public abstract class AbstractToOneAttributeSourceImpl extends AbstractHbmSource
// todo : handle batch fetches? // todo : handle batch fetches?
if ( getFetchSelectionString() == null ) { if ( getFetchSelectionString() == null ) {
if ( getOuterJoinSelectionString() == null ) { if ( requiresImmediateFetch() ) {
return FetchStyle.JOIN;
}
else if ( getOuterJoinSelectionString() == null ) {
return FetchStyle.SELECT; return FetchStyle.SELECT;
} }
else { else {

View File

@ -0,0 +1,44 @@
/*
* 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 org.hibernate.jaxb.spi.hbm.JaxbKeyManyToOneElement;
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
/**
* @author Gail Badner
*/
public class IdentifierKeyManyToOneSourceImpl extends KeyManyToOneSourceImpl {
public IdentifierKeyManyToOneSourceImpl(
MappingDocument mappingDocument,
final JaxbKeyManyToOneElement keyManyToOneElement) {
super( mappingDocument, keyManyToOneElement, SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID );
}
@Override
public boolean areValuesIncludedInUpdateByDefault() {
return true;
}
}

View File

@ -163,7 +163,7 @@ class KeyAttributeSourceImpl
@Override @Override
public String getContainingTableName() { public String getContainingTableName() {
return null; //To change body of implemented methods use File | Settings | File Templates. return null;
} }
@Override @Override

View File

@ -0,0 +1,197 @@
/*
* 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.Collections;
import java.util.List;
import java.util.Map;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.engine.spi.CascadeStyles;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.jaxb.spi.hbm.JaxbColumnElement;
import org.hibernate.jaxb.spi.hbm.JaxbKeyManyToOneElement;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource;
import org.hibernate.metamodel.spi.source.MetaAttributeSource;
import org.hibernate.metamodel.spi.source.RelationalValueSource;
import org.hibernate.metamodel.spi.source.SingularAttributeSource;
import org.hibernate.type.ForeignKeyDirection;
/**
* Implementation for {@code <key-many-to-one/>} mappings
*
* @author Gail Badner
*/
class KeyManyToOneSourceImpl
extends AbstractToOneAttributeSourceImpl
implements SingularAttributeSource {
private final JaxbKeyManyToOneElement keyManyToOneElement;
private final List<RelationalValueSource> valueSources;
public KeyManyToOneSourceImpl(
MappingDocument mappingDocument,
final JaxbKeyManyToOneElement keyManyToOneElement,
final SingularAttributeBinding.NaturalIdMutability naturalIdMutability) {
super( mappingDocument, naturalIdMutability, null );
this.keyManyToOneElement = keyManyToOneElement;
this.valueSources = Helper.buildValueSources(
sourceMappingDocument(),
new Helper.ValueSourcesAdapter() {
@Override
public String getColumnAttribute() {
return keyManyToOneElement.getColumnAttribute();
}
@Override
public String getFormulaAttribute() {
return null;
}
@Override
public List<JaxbColumnElement> getColumn() {
return keyManyToOneElement.getColumn();
}
@Override
public List<String> getFormula() {
return CollectionHelper.createEmptyList( String.class );
}
@Override
public String getContainingTableName() {
return null;
}
@Override
public boolean isIncludedInInsertByDefault() {
return true;
}
@Override
public boolean isIncludedInUpdateByDefault() {
return false;
}
}
);
}
@Override
public String getName() {
return keyManyToOneElement.getName();
}
@Override
public String getPropertyAccessorName() {
return keyManyToOneElement.getAccess();
}
@Override
public boolean isIncludedInOptimisticLocking() {
return false;
}
@Override
public Nature getNature() {
return Nature.MANY_TO_ONE;
}
@Override
public boolean isVirtualAttribute() {
return false;
}
@Override
protected boolean requiresImmediateFetch() {
return false;
}
@Override
protected String getFetchSelectionString() {
return null;
}
@Override
protected String getLazySelectionString() {
return keyManyToOneElement.getLazy() != null ?
keyManyToOneElement.getLazy().value() :
null;
}
@Override
protected String getOuterJoinSelectionString() {
return null;
}
@Override
public boolean areValuesIncludedInInsertByDefault() {
return true;
}
@Override
public boolean areValuesIncludedInUpdateByDefault() {
return true;
}
@Override
public boolean areValuesNullableByDefault() {
return false;
}
@Override
public String getContainingTableName() {
return null;
}
@Override
public List<RelationalValueSource> relationalValueSources() {
return valueSources;
}
@Override
public Iterable<? extends MetaAttributeSource> getMetaAttributeSources() {
return keyManyToOneElement.getMeta();
}
@Override
public String getReferencedEntityName() {
return keyManyToOneElement.getEntityName();
}
@Override
public ForeignKeyDirection getForeignKeyDirection() {
return ForeignKeyDirection.TO_PARENT;
}
@Override
public Iterable<CascadeStyle> getCascadeStyles() {
return Collections.singleton( CascadeStyles.NONE );
}
@Override
public String getExplicitForeignKeyName() {
return keyManyToOneElement.getForeignKey();
}
}

View File

@ -112,6 +112,11 @@ class ManyToOneAttributeSourceImpl extends AbstractToOneAttributeSourceImpl {
return Helper.interpretCascadeStyles( manyToOneElement.getCascade(), bindingContext() ); return Helper.interpretCascadeStyles( manyToOneElement.getCascade(), bindingContext() );
} }
@Override
protected boolean requiresImmediateFetch() {
return false;
}
@Override @Override
protected String getFetchSelectionString() { protected String getFetchSelectionString() {
return manyToOneElement.getFetch() != null ? return manyToOneElement.getFetch() != null ?

View File

@ -145,6 +145,11 @@ class OneToOneAttributeSourceImpl extends AbstractToOneAttributeSourceImpl {
return false; return false;
} }
@Override
protected boolean requiresImmediateFetch() {
return !oneToOneElement.isConstrained();
}
@Override @Override
public boolean areValuesIncludedInInsertByDefault() { public boolean areValuesIncludedInInsertByDefault() {
return true; return true;

View File

@ -29,7 +29,6 @@ import java.util.List;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.EntityMode; import org.hibernate.EntityMode;
import org.hibernate.TruthValue; import org.hibernate.TruthValue;
import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.engine.OptimisticLockStyle; import org.hibernate.engine.OptimisticLockStyle;
import org.hibernate.id.EntityIdentifierNature; import org.hibernate.id.EntityIdentifierNature;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
@ -41,6 +40,7 @@ import org.hibernate.jaxb.spi.hbm.JaxbKeyManyToOneElement;
import org.hibernate.jaxb.spi.hbm.JaxbKeyPropertyElement; import org.hibernate.jaxb.spi.hbm.JaxbKeyPropertyElement;
import org.hibernate.jaxb.spi.hbm.JaxbMultiTenancyElement; import org.hibernate.jaxb.spi.hbm.JaxbMultiTenancyElement;
import org.hibernate.jaxb.spi.hbm.JaxbNaturalIdElement; import org.hibernate.jaxb.spi.hbm.JaxbNaturalIdElement;
import org.hibernate.jaxb.spi.hbm.JaxbPolymorphismAttribute;
import org.hibernate.mapping.PropertyGeneration; import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.spi.binding.Caching; import org.hibernate.metamodel.spi.binding.Caching;
import org.hibernate.metamodel.spi.binding.IdGenerator; import org.hibernate.metamodel.spi.binding.IdGenerator;
@ -63,6 +63,7 @@ import org.hibernate.metamodel.spi.source.VersionAttributeSource;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
* @author Gail Badner
*/ */
public class RootEntitySourceImpl extends AbstractEntitySourceImpl implements RootEntitySource { public class RootEntitySourceImpl extends AbstractEntitySourceImpl implements RootEntitySource {
private final TableSpecificationSource primaryTable; private final TableSpecificationSource primaryTable;
@ -160,7 +161,7 @@ public class RootEntitySourceImpl extends AbstractEntitySourceImpl implements Ro
@Override @Override
public boolean isExplicitPolymorphism() { public boolean isExplicitPolymorphism() {
return "explicit".equals( entityElement().getPolymorphism() ); return JaxbPolymorphismAttribute.EXPLICIT == entityElement().getPolymorphism();
} }
@Override @Override
@ -444,14 +445,11 @@ public class RootEntitySourceImpl extends AbstractEntitySourceImpl implements Ro
@Override @Override
protected List<AttributeSource> buildAttributeSources() { protected List<AttributeSource> buildAttributeSources() {
List<AttributeSource> attributeSources = new ArrayList<AttributeSource>(); List<AttributeSource> attributeSources = new ArrayList<AttributeSource>();
// for ( Object attributeElement : compositeIdElement().getKeyPropertyOrKeyManyToOne() ) {
// attributeSources.add( buildAttributeSource( attributeElement ) );
// }
for ( JaxbKeyPropertyElement keyProperty : compositeIdElement().getKeyProperty()){ for ( JaxbKeyPropertyElement keyProperty : compositeIdElement().getKeyProperty()){
attributeSources.add( new IdentifierKeyAttributeSourceImpl( sourceMappingDocument(), keyProperty ) ); attributeSources.add( new IdentifierKeyAttributeSourceImpl( sourceMappingDocument(), keyProperty ) );
} }
for (JaxbKeyManyToOneElement element : compositeIdElement().getKeyManyToOne()){ for (JaxbKeyManyToOneElement keyManyToOne : compositeIdElement().getKeyManyToOne()){
throw new NotYetImplementedException( "key-many-to-one is not supported yet" ); attributeSources.add( new IdentifierKeyManyToOneSourceImpl( sourceMappingDocument(), keyManyToOne ) );
} }
return attributeSources; return attributeSources;
} }
@ -525,20 +523,11 @@ public class RootEntitySourceImpl extends AbstractEntitySourceImpl implements Ro
public List<SingularAttributeSource> getAttributeSourcesMakingUpIdentifier() { public List<SingularAttributeSource> getAttributeSourcesMakingUpIdentifier() {
final List<SingularAttributeSource> attributeSources = new ArrayList<SingularAttributeSource>(); final List<SingularAttributeSource> attributeSources = new ArrayList<SingularAttributeSource>();
final JaxbCompositeIdElement compositeId = entityElement().getCompositeId(); final JaxbCompositeIdElement compositeId = entityElement().getCompositeId();
for(final JaxbKeyPropertyElement keyProperty: compositeId.getKeyProperty()) { for ( final JaxbKeyPropertyElement keyProperty: compositeId.getKeyProperty() ) {
attributeSources.add( new IdentifierKeyAttributeSourceImpl( sourceMappingDocument(), keyProperty ) ); attributeSources.add( new IdentifierKeyAttributeSourceImpl( sourceMappingDocument(), keyProperty ) );
} }
for(final JaxbKeyManyToOneElement keyProperty : compositeId.getKeyManyToOne()){ for ( final JaxbKeyManyToOneElement keyManyToOne : compositeId.getKeyManyToOne() ){
// final AttributeSource attributeSource = buildAttributeSource( attributeSources.add( new IdentifierKeyManyToOneSourceImpl( sourceMappingDocument(), keyManyToOne ) );
// keyProperty,
// null,
// SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID
// );
// if ( ! attributeSource.isSingular() ) {
// throw new HibernateException( "Only singular attributes are supported for composite identifiers" );
// }
// attributeSources.add( (SingularAttributeSource) attributeSource );
//todo : implement
} }
return attributeSources; return attributeSources;

View File

@ -154,7 +154,8 @@ public abstract class AbstractAttributeBindingContainer implements AttributeBind
MetaAttributeContext metaAttributeContext, MetaAttributeContext metaAttributeContext,
EntityBinding referencedEntityBinding, EntityBinding referencedEntityBinding,
SingularAttributeBinding referencedAttributeBinding, SingularAttributeBinding referencedAttributeBinding,
boolean isConstrained) { boolean isConstrained,
List<RelationalValueBinding> valueBindings) {
final OneToOneAttributeBinding binding = new OneToOneAttributeBinding( final OneToOneAttributeBinding binding = new OneToOneAttributeBinding(
this, this,
attribute, attribute,
@ -165,7 +166,8 @@ public abstract class AbstractAttributeBindingContainer implements AttributeBind
metaAttributeContext, metaAttributeContext,
referencedEntityBinding, referencedEntityBinding,
referencedAttributeBinding, referencedAttributeBinding,
isConstrained isConstrained,
valueBindings
); );
registerAttributeBinding( binding ); registerAttributeBinding( binding );
return binding; return binding;

View File

@ -151,7 +151,8 @@ public abstract class AbstractCompositeAttributeBindingContainer
MetaAttributeContext metaAttributeContext, MetaAttributeContext metaAttributeContext,
EntityBinding referencedEntityBinding, EntityBinding referencedEntityBinding,
SingularAttributeBinding referencedAttributeBinding, SingularAttributeBinding referencedAttributeBinding,
boolean isConstrained) { boolean isConstrained,
List<RelationalValueBinding> valueBindings) {
if ( !isModifiable() ) { if ( !isModifiable() ) {
throw new UnsupportedOperationException( "Attribute bindings are read-only and cannot be modified." ); throw new UnsupportedOperationException( "Attribute bindings are read-only and cannot be modified." );
} }
@ -164,7 +165,8 @@ public abstract class AbstractCompositeAttributeBindingContainer
metaAttributeContext, metaAttributeContext,
referencedEntityBinding, referencedEntityBinding,
referencedAttributeBinding, referencedAttributeBinding,
isConstrained isConstrained,
valueBindings
); );
} }

View File

@ -164,9 +164,7 @@ public interface AttributeBindingContainer {
MetaAttributeContext metaAttributeContext); MetaAttributeContext metaAttributeContext);
/** /**
* Factory method for many-to-one attribute bindings. * Factory method for one-to-one attribute bindings.
*
*
* *
* @param attribute The attribute for which to make a binding. * @param attribute The attribute for which to make a binding.
* @param propertyAccessorName * @param propertyAccessorName
@ -187,7 +185,8 @@ public interface AttributeBindingContainer {
MetaAttributeContext metaAttributeContext, MetaAttributeContext metaAttributeContext,
EntityBinding referencedEntityBinding, EntityBinding referencedEntityBinding,
SingularAttributeBinding referencedAttributeBinding, SingularAttributeBinding referencedAttributeBinding,
boolean isConstrained); boolean isConstrained,
List<RelationalValueBinding> valueBindings);
/** /**

View File

@ -404,7 +404,8 @@ public class CompositeAttributeBinding
MetaAttributeContext metaAttributeContext, MetaAttributeContext metaAttributeContext,
EntityBinding referencedEntityBinding, EntityBinding referencedEntityBinding,
SingularAttributeBinding referencedAttributeBinding, SingularAttributeBinding referencedAttributeBinding,
boolean isConstrained) { boolean isConstrained,
List<RelationalValueBinding> valueBindings) {
return compositeAttributeBindingContainer.makeOneToOneAttributeBinding( return compositeAttributeBindingContainer.makeOneToOneAttributeBinding(
attribute, attribute,
propertyAccessorName, propertyAccessorName,
@ -414,7 +415,8 @@ public class CompositeAttributeBinding
metaAttributeContext, metaAttributeContext,
referencedEntityBinding, referencedEntityBinding,
referencedAttributeBinding, referencedAttributeBinding,
isConstrained isConstrained,
valueBindings
); );
} }

View File

@ -394,15 +394,6 @@ public class EntityIdentifier {
) )
); );
} }
if ( attributeBinding.isAssociation() ) {
throw new MappingException(
String.format(
"The composite ID for [%s] contains an attribute [%s} that is an association.",
entityBinding.getEntity().getName(),
attributeBinding.getAttribute().getName()
)
);
}
} }
} }

View File

@ -49,7 +49,8 @@ public class OneToOneAttributeBinding
MetaAttributeContext metaAttributeContext, MetaAttributeContext metaAttributeContext,
EntityBinding referencedEntityBinding, EntityBinding referencedEntityBinding,
SingularAttributeBinding referencedAttributeBinding, SingularAttributeBinding referencedAttributeBinding,
boolean isConstrained) { boolean isConstrained,
List<RelationalValueBinding> valueBindings) {
super( super(
container, container,
attribute, attribute,
@ -59,9 +60,8 @@ public class OneToOneAttributeBinding
naturalIdMutability, naturalIdMutability,
metaAttributeContext, metaAttributeContext,
referencedEntityBinding, referencedEntityBinding,
CollectionHelper.createEmptyList( RelationalValueBinding.class ), valueBindings,
referencedAttributeBinding referencedAttributeBinding
); );
this.isConstrained = isConstrained; this.isConstrained = isConstrained;
} }

View File

@ -1,8 +1,13 @@
package org.hibernate.test.annotations.derivedidentities.e2.a; package org.hibernate.test.annotations.derivedidentities.e2.a;
import java.util.List;
import org.junit.Test; import org.junit.Test;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.metamodel.spi.relational.Column;
import org.hibernate.metamodel.spi.relational.PrimaryKey;
import org.hibernate.metamodel.spi.relational.TableSpecification;
import org.hibernate.test.util.SchemaUtil; import org.hibernate.test.util.SchemaUtil;
import org.hibernate.testing.FailureExpectedWithNewMetamodel; import org.hibernate.testing.FailureExpectedWithNewMetamodel;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
@ -23,6 +28,12 @@ public class DerivedIdentityIdClassParentIdClassDepTest extends BaseCoreFunction
assertTrue( SchemaUtil.isColumnPresent( "Dependent", "name", metadata() ) ); assertTrue( SchemaUtil.isColumnPresent( "Dependent", "name", metadata() ) );
assertTrue( ! SchemaUtil.isColumnPresent( "Dependent", "firstName", metadata() ) ); assertTrue( ! SchemaUtil.isColumnPresent( "Dependent", "firstName", metadata() ) );
assertTrue( ! SchemaUtil.isColumnPresent( "Dependent", "lastName", metadata() ) ); assertTrue( ! SchemaUtil.isColumnPresent( "Dependent", "lastName", metadata() ) );
final TableSpecification dependentTable = SchemaUtil.getTable( "Dependent", metadata() );
final List<Column> dependentPkColumns = dependentTable.getPrimaryKey().getColumns();
assertEquals( 3, dependentPkColumns.size() );
assertTrue( dependentPkColumns.contains( dependentTable.locateColumn( "name" ) ) );
assertTrue( dependentPkColumns.contains( dependentTable.locateColumn( "FK1" ) ) );
assertTrue( dependentPkColumns.contains( dependentTable.locateColumn( "FK2" ) ) );
Employee e = new Employee(); Employee e = new Employee();
e.firstName = "Emmanuel"; e.firstName = "Emmanuel";
e.lastName = "Bernard"; e.lastName = "Bernard";

View File

@ -38,7 +38,6 @@ import static org.junit.Assert.assertEquals;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
@FailureExpectedWithNewMetamodel
public class IdentifierPropertyReferencesTest extends BaseCoreFunctionalTestCase { public class IdentifierPropertyReferencesTest extends BaseCoreFunctionalTestCase {
@Override @Override
public String[] getMappings() { public String[] getMappings() {

View File

@ -52,7 +52,6 @@ import static org.junit.Assert.fail;
/** /**
* @author Gavin King * @author Gavin King
*/ */
@FailureExpectedWithNewMetamodel
public class ImmutableTest extends BaseCoreFunctionalTestCase { public class ImmutableTest extends BaseCoreFunctionalTestCase {
private static class TextAsMaterializedClobType extends AbstractSingleColumnStandardBasicType<String> { private static class TextAsMaterializedClobType extends AbstractSingleColumnStandardBasicType<String> {
public final static TextAsMaterializedClobType INSTANCE = new TextAsMaterializedClobType(); public final static TextAsMaterializedClobType INSTANCE = new TextAsMaterializedClobType();
@ -853,6 +852,7 @@ public class ImmutableTest extends BaseCoreFunctionalTestCase {
} }
@Test @Test
@FailureExpectedWithNewMetamodel
public void testImmutableCollectionWithUpdate() { public void testImmutableCollectionWithUpdate() {
clearCounts(); clearCounts();
@ -1074,6 +1074,7 @@ public class ImmutableTest extends BaseCoreFunctionalTestCase {
} }
@Test @Test
@FailureExpectedWithNewMetamodel
public void testImmutableCollectionWithMerge() { public void testImmutableCollectionWithMerge() {
clearCounts(); clearCounts();

View File

@ -50,7 +50,6 @@ import static org.junit.Assert.fail;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
@SuppressWarnings( {"unchecked"}) @SuppressWarnings( {"unchecked"})
@FailureExpectedWithNewMetamodel
public class EagerKeyManyToOneTest extends BaseCoreFunctionalTestCase { public class EagerKeyManyToOneTest extends BaseCoreFunctionalTestCase {
@Override @Override
public String[] getMappings() { public String[] getMappings() {

View File

@ -37,7 +37,6 @@ import static org.junit.Assert.assertEquals;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
@FailureExpectedWithNewMetamodel
public class LazyKeyManyToOneTest extends BaseCoreFunctionalTestCase { public class LazyKeyManyToOneTest extends BaseCoreFunctionalTestCase {
@Override @Override
public String[] getMappings() { public String[] getMappings() {

View File

@ -38,7 +38,6 @@ import org.junit.Test;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
@FailureExpectedWithNewMetamodel
public class KeyManyToOneTest extends BaseCoreFunctionalTestCase { public class KeyManyToOneTest extends BaseCoreFunctionalTestCase {
@Override @Override
public String[] getMappings() { public String[] getMappings() {
@ -52,6 +51,7 @@ public class KeyManyToOneTest extends BaseCoreFunctionalTestCase {
} }
@Test @Test
@FailureExpectedWithNewMetamodel
public void testCriteriaRestrictionOnKeyManyToOne() { public void testCriteriaRestrictionOnKeyManyToOne() {
Session s = openSession(); Session s = openSession();
s.beginTransaction(); s.beginTransaction();

View File

@ -42,7 +42,6 @@ import static org.junit.Assert.assertNull;
/** /**
* @author Gavin King * @author Gavin King
*/ */
@FailureExpectedWithNewMetamodel
public class DiscrimSubclassOneToOneTest extends BaseCoreFunctionalTestCase { public class DiscrimSubclassOneToOneTest extends BaseCoreFunctionalTestCase {
@Override @Override
public String[] getMappings() { public String[] getMappings() {

View File

@ -336,7 +336,7 @@ public abstract class BaseCoreFunctionalTestCase extends BaseUnitTestCase {
} }
} }
} }
if ( !hasLob && !entityBinding.getHierarchyDetails().isExplicitPolymorphism() && overrideCacheStrategy() ) { if ( !hasLob && entityBinding.getSuperEntityBinding() == null && overrideCacheStrategy() ) {
Caching caching = entityBinding.getHierarchyDetails().getCaching(); Caching caching = entityBinding.getHierarchyDetails().getCaching();
if ( caching == null ) { if ( caching == null ) {
caching = new Caching(); caching = new Caching();