HHH-7983 : RelationalValueBindingContainer

This commit is contained in:
Gail Badner 2013-02-01 13:00:02 -08:00
parent 974e43a5fb
commit 1634d56c36
27 changed files with 390 additions and 434 deletions

View File

@ -203,12 +203,14 @@ public class Binder {
private final LinkedList<InheritanceType> inheritanceTypes = new LinkedList<InheritanceType>();
private final LinkedList<EntityMode> entityModes = new LinkedList<EntityMode>();
private final HibernateTypeHelper typeHelper; // todo: refactor helper and remove redundant methods in this class
private final ForeignKeyHelper foreignKeyHelper;
public Binder(final MetadataImplementor metadata,
final IdentifierGeneratorFactory identifierGeneratorFactory) {
this.metadata = metadata;
this.identifierGeneratorFactory = identifierGeneratorFactory;
this.typeHelper = new HibernateTypeHelper( this, metadata );
this.foreignKeyHelper = new ForeignKeyHelper( this );
this.nameNormalizer = metadata.getObjectNameNormalizer();
}
@ -678,9 +680,9 @@ public class Binder {
);
// TODO: make the foreign key column the primary key???
final ForeignKey foreignKey = bindForeignKey(
final ForeignKey foreignKey = locateOrCreateForeignKey(
quotedIdentifier( secondaryTableSource.getExplicitForeignKeyName() ),
extractColumnsFromRelationalValueBindings( joinRelationalValueBindings ),
joinRelationalValueBindings,
determineForeignKeyTargetColumns( entityBinding, secondaryTableSource )
);
SecondaryTable secondaryTable = new SecondaryTable( table, foreignKey );
@ -692,6 +694,34 @@ public class Binder {
}
}
public ForeignKey locateOrCreateForeignKey(
final String foreignKeyName,
final List<RelationalValueBinding> sourceRelationalValueBindings,
final List<Column> targetColumns) {
return foreignKeyHelper.locateOrCreateForeignKey(
foreignKeyName,
extractColumnsFromRelationalValueBindings( sourceRelationalValueBindings ),
targetColumns
);
}
// TODO: try to get rid of this...
private static List<Column> extractColumnsFromRelationalValueBindings(
final List<RelationalValueBinding> valueBindings) {
List<Column> columns = new ArrayList<Column>( valueBindings.size() );
for ( RelationalValueBinding relationalValueBinding : valueBindings ) {
final Value value = relationalValueBinding.getValue();
// todo : currently formulas are not supported here... :(
if ( !Column.class.isInstance( value ) ) {
throw new NotYetImplementedException(
"Derived values are not supported when creating a foreign key that targets columns."
);
}
columns.add( (Column) value );
}
return columns;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ identifier binding relates methods
private void bindIdentifier(
final EntityBinding rootEntityBinding,
@ -1159,10 +1189,10 @@ public class Binder {
attributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping(),
attributeBinding.getRelationalValueBindings()
);
if ( !hasDerivedValue( attributeBinding.getRelationalValueBindings() ) ) {
bindForeignKey(
if ( !attributeBinding.hasDerivedValue() ) {
locateOrCreateForeignKey(
quotedIdentifier( attributeSource.getExplicitForeignKeyName() ),
extractColumnsFromRelationalValueBindings( attributeBinding.getRelationalValueBindings() ),
attributeBinding.getRelationalValueBindings(),
determineForeignKeyTargetColumns(
attributeBinding.getReferencedEntityBinding(),
attributeSource
@ -1271,19 +1301,18 @@ public class Binder {
toOneAttributeBindingContext
);
if ( attributeSource.getForeignKeyDirection() == ForeignKeyDirection.FROM_PARENT ) {
List<Column> foreignKeyColumns = extractColumnsFromRelationalValueBindings(
List<RelationalValueBinding> foreignKeyRelationalValueBindings =
attributeBinding
.getContainer()
.seekEntityBinding()
.getHierarchyDetails()
.getEntityIdentifier()
.getAttributeBinding()
.getRelationalValueBindings()
);
.getRelationalValueBindings();
bindForeignKey(
locateOrCreateForeignKey(
quotedIdentifier( attributeSource.getExplicitForeignKeyName() ),
foreignKeyColumns,
foreignKeyRelationalValueBindings,
determineForeignKeyTargetColumns(
attributeBinding.getReferencedEntityBinding(),
attributeSource
@ -1865,10 +1894,10 @@ public class Binder {
);
if ( !elementBinding.getPluralAttributeBinding().getPluralAttributeKeyBinding().isInverse() &&
!hasDerivedValue( elementBinding.getRelationalValueBindings() ) ) {
bindForeignKey(
!elementBinding.hasDerivedValue() ) {
locateOrCreateForeignKey(
quotedIdentifier( elementSource.getExplicitForeignKeyName() ),
extractColumnsFromRelationalValueBindings( elementBinding.getRelationalValueBindings() ),
elementBinding.getRelationalValueBindings(),
targetColumns
);
}
@ -1927,7 +1956,6 @@ public class Binder {
referencedAttributeBinding.getReferencedAttributeBinding()
.getHibernateTypeDescriptor()
);
boolean isUpdatable = false;
List<RelationalValueBinding> sourceColumnBindings = referencedAttributeBinding.getRelationalValueBindings();
List<Column> sourceColumns = new ArrayList<Column>();
for ( RelationalValueBinding relationalValueBinding : sourceColumnBindings ) {
@ -1935,14 +1963,13 @@ public class Binder {
if ( Column.class.isInstance( v ) ) {
sourceColumns.add( Column.class.cast( v ) );
}
isUpdatable = isUpdatable || relationalValueBinding.isIncludeInUpdate();
}
for ( ForeignKey fk : referencedEntityBinding.getPrimaryTable().getForeignKeys() ) {
if ( fk.getSourceColumns().equals( sourceColumns ) ) {
keyBinding.setForeignKey( fk );
keyBinding.setCascadeDeleteEnabled( fk.getDeleteRule() == ForeignKey.ReferentialAction.CASCADE );
}
}
keyBinding.setUpdatable( isUpdatable );
keyBinding.setRelationalValueBindings( sourceColumnBindings );
}
else {
bindCollectionTableForeignKey( attributeBinding, attributeSource.getKeySource(), collectionTable );
@ -2300,7 +2327,7 @@ public class Binder {
)
);
}
if ( hasAnyNonNullableColumns( elementBinding.getRelationalValueBindings() ) ) {
if ( elementBinding.hasNonNullableValue() ) {
bindSetCollectionTablePrimaryKey( attributeBinding );
}
else {
@ -2315,9 +2342,10 @@ public class Binder {
final PrimaryKey primaryKey = attributeBinding.getPluralAttributeKeyBinding()
.getCollectionTable()
.getPrimaryKey();
final ForeignKey foreignKey = attributeBinding.getPluralAttributeKeyBinding().getForeignKey();
for ( final Column foreignKeyColumn : foreignKey.getSourceColumns() ) {
primaryKey.addColumn( foreignKeyColumn );
final List<RelationalValueBinding> keyValueBindings =
attributeBinding.getPluralAttributeKeyBinding().getRelationalValueBindings();
for ( final RelationalValueBinding keyRelationalValueBinding : keyValueBindings ) {
primaryKey.addColumn( (Column) keyRelationalValueBinding.getValue() );
}
for ( final RelationalValueBinding elementValueBinding : elementBinding.getRelationalValueBindings() ) {
if ( !elementValueBinding.isDerived() && !elementValueBinding.isNullable() ) {
@ -2357,7 +2385,7 @@ public class Binder {
);
}
List<RelationalValueBinding> sourceColumnBindings =
List<RelationalValueBinding> sourceRelationalBindings =
bindValues(
attributeBindingContainer,
keySource,
@ -2367,33 +2395,14 @@ public class Binder {
attributeBinding.getPluralAttributeElementBinding()
.getNature() != PluralAttributeElementBinding.Nature.ONE_TO_MANY
);
// Determine if the foreign key (source) column is updatable and also extract the columns out
// of the RelationalValueBindings.
boolean isInsertable = false;
boolean isUpdatable = false;
List<Column> sourceColumns = new ArrayList<Column>( sourceColumnBindings.size() );
for ( RelationalValueBinding relationalValueBinding : sourceColumnBindings ) {
final Value value = relationalValueBinding.getValue();
// todo : currently formulas are not supported here... :(
if ( !Column.class.isInstance( value ) ) {
throw new NotYetImplementedException(
"Derived values are not supported when creating a foreign key that targets columns."
);
}
isInsertable = isInsertable || relationalValueBinding.isIncludeInInsert();
isUpdatable = isUpdatable || relationalValueBinding.isIncludeInUpdate();
sourceColumns.add( (Column) value );
}
keyBinding.setInsertable( isInsertable );
keyBinding.setUpdatable( isUpdatable );
ForeignKey foreignKey = bindForeignKey(
keyBinding.setRelationalValueBindings( sourceRelationalBindings );
ForeignKey foreignKey = locateOrCreateForeignKey(
quotedIdentifier( keySource.getExplicitForeignKeyName() ),
sourceColumns,
sourceRelationalBindings,
targetColumns
);
foreignKey.setDeleteRule( keySource.getOnDeleteAction() );
keyBinding.setForeignKey( foreignKey );
keyBinding.setCascadeDeleteEnabled( keySource.getOnDeleteAction() == ForeignKey.ReferentialAction.CASCADE );
final HibernateTypeDescriptor pluralAttributeKeyTypeDescriptor = keyBinding.getHibernateTypeDescriptor();
pluralAttributeKeyTypeDescriptor.copyFrom(
@ -2402,15 +2411,15 @@ public class Binder {
);
final Type resolvedKeyType = pluralAttributeKeyTypeDescriptor.getResolvedTypeMapping();
Iterator<Column> fkColumnIterator = keyBinding.getForeignKey().getSourceColumns().iterator();
Iterator<RelationalValueBinding> fkColumnIterator = keyBinding.getRelationalValueBindings().iterator();
if ( resolvedKeyType.isComponentType() ) {
ComponentType componentType = (ComponentType) resolvedKeyType;
for ( Type subType : componentType.getSubtypes() ) {
typeHelper.bindJdbcDataType( subType, fkColumnIterator.next() );
typeHelper.bindJdbcDataType( subType, fkColumnIterator.next().getValue() );
}
}
else {
typeHelper.bindJdbcDataType( resolvedKeyType, fkColumnIterator.next() );
typeHelper.bindJdbcDataType( resolvedKeyType, fkColumnIterator.next().getValue() );
}
}
@ -2522,7 +2531,7 @@ public class Binder {
subclassEntitySource
);
ForeignKey foreignKey = bindForeignKey(
ForeignKey foreignKey = foreignKeyHelper.locateOrCreateForeignKey(
quotedIdentifier( subclassEntitySource.getExplicitForeignKeyName() ),
sourceColumns,
targetColumns
@ -2538,64 +2547,6 @@ public class Binder {
}
private ForeignKey bindForeignKey(
final String foreignKeyName,
final List<Column> sourceColumns,
final List<Column> targetColumns) {
ForeignKey foreignKey = null;
if ( foreignKeyName != null ) {
foreignKey = locateAndBindForeignKeyByName( foreignKeyName, sourceColumns, targetColumns );
}
if ( foreignKey == null ) {
foreignKey = locateForeignKeyByColumnMapping( sourceColumns, targetColumns );
if ( foreignKey != null && foreignKeyName != null ) {
if ( foreignKey.getName() == null ) {
// the foreign key name has not be initialized; set it to foreignKeyName
foreignKey.setName( foreignKeyName );
}
else {
// the foreign key name has already been initialized so cannot rename it
// TODO: should this just be INFO?
log.warn(
String.format(
"A foreign key mapped as %s will not be created because foreign key %s already exists with the same column mapping.",
foreignKeyName,
foreignKey.getName()
)
);
}
}
}
if ( foreignKey == null ) {
// no foreign key found; create one
final TableSpecification sourceTable = sourceColumns.get( 0 ).getTable();
final TableSpecification targetTable = targetColumns.get( 0 ).getTable();
foreignKey = sourceTable.createForeignKey( targetTable, foreignKeyName );
bindForeignKeyColumns( foreignKey, sourceColumns, targetColumns );
}
return foreignKey;
}
private void bindForeignKeyColumns(
final ForeignKey foreignKey,
final List<Column> sourceColumns,
final List<Column> targetColumns) {
if ( sourceColumns.size() != targetColumns.size() ) {
throw bindingContext().makeMappingException(
String.format(
"Non-matching number columns in foreign key source columns [%s : %s] and target columns [%s : %s]",
sourceColumns.get( 0 ).getTable().getLogicalName().getText(),
sourceColumns.size(),
targetColumns.get( 0 ).getTable().getLogicalName().getText(),
targetColumns.size()
)
);
}
for ( int i = 0; i < sourceColumns.size(); i++ ) {
foreignKey.addColumnMapping( sourceColumns.get( i ), targetColumns.get( i ) );
}
}
private TableSpecification locateDefaultTableSpecificationForAttribute(
final AttributeBindingContainer attributeBindingContainer,
final SingularAttributeSource attributeSource) {
@ -2771,7 +2722,7 @@ public class Binder {
new ColumnNamingStrategyHelper( defaultName, isDefaultAttributeName )
);
final Column column = table.locateOrCreateColumn( resolvedColumnName );
resolveColumnNullabl( columnSource, forceNotNull, isNullableByDefault, column );
resolveColumnNullable( columnSource, forceNotNull, isNullableByDefault, column );
column.setDefaultValue( columnSource.getDefaultValue() );
column.setSqlType( columnSource.getSqlType() );
column.setSize( columnSource.getSize() );
@ -2784,7 +2735,7 @@ public class Binder {
return column;
}
private void resolveColumnNullabl(
private void resolveColumnNullable(
final ColumnSource columnSource,
final boolean forceNotNull,
final boolean isNullableByDefault,
@ -2958,50 +2909,6 @@ public class Binder {
}
}
private ForeignKey locateAndBindForeignKeyByName(
final String foreignKeyName,
final List<Column> sourceColumns,
final List<Column> targetColumns) {
if ( foreignKeyName == null ) {
throw new AssertionFailure( "foreignKeyName must be non-null." );
}
final TableSpecification sourceTable = sourceColumns.get( 0 ).getTable();
final TableSpecification targetTable = targetColumns.get( 0 ).getTable();
ForeignKey foreignKey = sourceTable.locateForeignKey( foreignKeyName );
if ( foreignKey != null ) {
if ( !targetTable.equals( foreignKey.getTargetTable() ) ) {
throw bindingContext().makeMappingException(
String.format(
"Unexpected target table defined for foreign key \"%s\"; expected \"%s\"; found \"%s\"",
foreignKeyName,
targetTable.getLogicalName(),
foreignKey.getTargetTable().getLogicalName()
)
);
}
// check if source and target columns have been bound already
if ( foreignKey.getColumnSpan() == 0 ) {
// foreign key was found, but no columns bound to it yet
bindForeignKeyColumns( foreignKey, sourceColumns, targetColumns );
}
else {
// The located foreign key already has columns bound;
// Make sure they are the same columns.
if ( !foreignKey.getSourceColumns().equals( sourceColumns ) ||
foreignKey.getTargetColumns().equals( targetColumns ) ) {
throw bindingContext().makeMappingException(
String.format(
"Attempt to bind exisitng foreign key \"%s\" with different columns.",
foreignKeyName
)
);
}
}
}
return foreignKey;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ simple instance helper methods
private void mapSourcesByName(final EntitySource rootEntitySource) {
String entityName = rootEntitySource.getEntityName();
@ -3086,10 +2993,11 @@ public class Binder {
final PrimaryKey primaryKey = attributeBinding.getPluralAttributeKeyBinding()
.getCollectionTable()
.getPrimaryKey();
final ForeignKey foreignKey = attributeBinding.getPluralAttributeKeyBinding().getForeignKey();
final List<RelationalValueBinding> keyRelationalValueBindings =
attributeBinding.getPluralAttributeKeyBinding().getRelationalValueBindings();
final PluralAttributeIndexBinding indexBinding = attributeBinding.getPluralAttributeIndexBinding();
for ( final Column foreignKeyColumn : foreignKey.getSourceColumns() ) {
primaryKey.addColumn( foreignKeyColumn );
for ( final RelationalValueBinding keyRelationalValueBinding : keyRelationalValueBindings ) {
primaryKey.addColumn( (Column) keyRelationalValueBinding.getValue() );
}
for ( RelationalValueBinding relationalValueBinding : indexBinding.getRelationalValueBindings() ) {
if ( !relationalValueBinding.isDerived() ) {
@ -3122,16 +3030,6 @@ public class Binder {
return fullPath.substring( attributeBinding.getContainer().seekEntityBinding().getEntityName().length() + 1 );
}
private static boolean hasDerivedValue(
final List<RelationalValueBinding> relationalValueBindings) {
for ( RelationalValueBinding relationalValueBinding : relationalValueBindings ) {
if ( DerivedValue.class.isInstance( relationalValueBinding.getValue() ) ) {
return true;
}
}
return false;
}
// TODO: should this be moved to CascadeStyles as a static method?
// TODO: sources already factor in default cascade; should that be done here instead?
private static CascadeStyle determineCascadeStyle(
@ -3203,60 +3101,12 @@ public class Binder {
.createSingularAttribute( attributeSource.getName() );
}
private static ForeignKey locateForeignKeyByColumnMapping(
final List<Column> sourceColumns,
final List<Column> targetColumns) {
final TableSpecification sourceTable = sourceColumns.get( 0 ).getTable();
final TableSpecification targetTable = targetColumns.get( 0 ).getTable();
// check for an existing foreign key with the same source/target columns
ForeignKey foreignKey = null;
Iterable<ForeignKey> possibleForeignKeys = sourceTable.locateForeignKey( targetTable );
if ( possibleForeignKeys != null ) {
for ( ForeignKey possibleFK : possibleForeignKeys ) {
if ( possibleFK.getSourceColumns().equals( sourceColumns ) &&
possibleFK.getTargetColumns().equals( targetColumns ) ) {
// this is the foreign key
foreignKey = possibleFK;
break;
}
}
}
return foreignKey;
}
private static String attributeSourcesByNameKey(
final String entityName,
final String attributeName) {
return entityName + "." + attributeName;
}
// TODO: try to get rid of this...
private static List<Column> extractColumnsFromRelationalValueBindings(
final List<RelationalValueBinding> valueBindings) {
List<Column> columns = new ArrayList<Column>( valueBindings.size() );
for ( RelationalValueBinding relationalValueBinding : valueBindings ) {
final Value value = relationalValueBinding.getValue();
// todo : currently formulas are not supported here... :(
if ( !Column.class.isInstance( value ) ) {
throw new NotYetImplementedException(
"Derived values are not supported when creating a foreign key that targets columns."
);
}
columns.add( (Column) value );
}
return columns;
}
private static boolean hasAnyNonNullableColumns(
final List<RelationalValueBinding> relationalValueBindings) {
for ( RelationalValueBinding relationalValueBinding : relationalValueBindings ) {
if ( Column.class.isInstance( relationalValueBinding.getValue() ) && !relationalValueBinding.isNullable() ) {
return true;
}
}
return false;
}
static String createAttributePath(
final AttributeBinding attributeBinding) {
return attributeBinding.getContainer().getPathBase() + '.' + attributeBinding.getAttribute().getName();

View File

@ -0,0 +1,172 @@
/*
* 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;
import java.util.List;
import org.jboss.logging.Logger;
import org.hibernate.AssertionFailure;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.metamodel.spi.relational.Column;
import org.hibernate.metamodel.spi.relational.ForeignKey;
import org.hibernate.metamodel.spi.relational.TableSpecification;
/**
* @author Gail Badner
*/
public class ForeignKeyHelper {
private static final CoreMessageLogger log = Logger.getMessageLogger(
CoreMessageLogger.class,
ForeignKeyHelper.class.getName()
);
private final Binder binder;
public ForeignKeyHelper(Binder binder) {
this.binder = binder;
}
public ForeignKey locateOrCreateForeignKey(
final String foreignKeyName,
final List<Column> sourceColumns,
final List<Column> targetColumns) {
ForeignKey foreignKey = null;
if ( foreignKeyName != null ) {
foreignKey = locateAndBindForeignKeyByName( foreignKeyName, sourceColumns, targetColumns );
}
if ( foreignKey == null ) {
foreignKey = locateForeignKeyByColumnMapping( sourceColumns, targetColumns );
if ( foreignKey != null && foreignKeyName != null ) {
if ( foreignKey.getName() == null ) {
// the foreign key name has not be initialized; set it to foreignKeyName
foreignKey.setName( foreignKeyName );
}
else {
// the foreign key name has already been initialized so cannot rename it
// TODO: should this just be INFO?
log.warn(
String.format(
"A foreign key mapped as %s will not be created because foreign key %s already exists with the same column mapping.",
foreignKeyName,
foreignKey.getName()
)
);
}
}
}
if ( foreignKey == null ) {
// no foreign key found; create one
final TableSpecification sourceTable = sourceColumns.get( 0 ).getTable();
final TableSpecification targetTable = targetColumns.get( 0 ).getTable();
foreignKey = sourceTable.createForeignKey( targetTable, foreignKeyName );
bindForeignKeyColumns( foreignKey, sourceColumns, targetColumns );
}
return foreignKey;
}
private static ForeignKey locateForeignKeyByColumnMapping(
final List<Column> sourceColumns,
final List<Column> targetColumns) {
final TableSpecification sourceTable = sourceColumns.get( 0 ).getTable();
final TableSpecification targetTable = targetColumns.get( 0 ).getTable();
// check for an existing foreign key with the same source/target columns
ForeignKey foreignKey = null;
Iterable<ForeignKey> possibleForeignKeys = sourceTable.locateForeignKey( targetTable );
if ( possibleForeignKeys != null ) {
for ( ForeignKey possibleFK : possibleForeignKeys ) {
if ( possibleFK.getSourceColumns().equals( sourceColumns ) &&
possibleFK.getTargetColumns().equals( targetColumns ) ) {
// this is the foreign key
foreignKey = possibleFK;
break;
}
}
}
return foreignKey;
}
private void bindForeignKeyColumns(
final ForeignKey foreignKey,
final List<Column> sourceColumns,
final List<Column> targetColumns) {
if ( sourceColumns.size() != targetColumns.size() ) {
throw binder.bindingContext().makeMappingException(
String.format(
"Non-matching number columns in foreign key source columns [%s : %s] and target columns [%s : %s]",
sourceColumns.get( 0 ).getTable().getLogicalName().getText(),
sourceColumns.size(),
targetColumns.get( 0 ).getTable().getLogicalName().getText(),
targetColumns.size()
)
);
}
for ( int i = 0; i < sourceColumns.size(); i++ ) {
foreignKey.addColumnMapping( sourceColumns.get( i ), targetColumns.get( i ) );
}
}
private ForeignKey locateAndBindForeignKeyByName(
final String foreignKeyName,
final List<Column> sourceColumns,
final List<Column> targetColumns) {
if ( foreignKeyName == null ) {
throw new AssertionFailure( "foreignKeyName must be non-null." );
}
final TableSpecification sourceTable = sourceColumns.get( 0 ).getTable();
final TableSpecification targetTable = targetColumns.get( 0 ).getTable();
ForeignKey foreignKey = sourceTable.locateForeignKey( foreignKeyName );
if ( foreignKey != null ) {
if ( !targetTable.equals( foreignKey.getTargetTable() ) ) {
throw binder.bindingContext().makeMappingException(
String.format(
"Unexpected target table defined for foreign key \"%s\"; expected \"%s\"; found \"%s\"",
foreignKeyName,
targetTable.getLogicalName(),
foreignKey.getTargetTable().getLogicalName()
)
);
}
// check if source and target columns have been bound already
if ( foreignKey.getColumnSpan() == 0 ) {
// foreign key was found, but no columns bound to it yet
bindForeignKeyColumns( foreignKey, sourceColumns, targetColumns );
}
else {
// The located foreign key already has columns bound;
// Make sure they are the same columns.
if ( !foreignKey.getSourceColumns().equals( sourceColumns ) ||
foreignKey.getTargetColumns().equals( targetColumns ) ) {
throw binder.bindingContext().makeMappingException(
String.format(
"Attempt to bind exisitng foreign key \"%s\" with different columns.",
foreignKeyName
)
);
}
}
}
return foreignKey;
}
}

View File

@ -408,7 +408,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
entityBindingMap.get(
pluralAttributeBinding.getPluralAttributeElementBinding().getHibernateTypeDescriptor().
getResolvedTypeMapping().getName() );
List<Column> columns = keyBinding.getForeignKey().getColumns();
List<RelationalValueBinding> keyValueBindings = keyBinding.getRelationalValueBindings();
boolean bidirectional = false;
for ( AttributeBinding attributeBinding : referencedEntityBinding.attributeBindings() ) {
if ( !(attributeBinding instanceof ManyToOneAttributeBinding) ) {
@ -423,12 +423,12 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
// Check if the many-to-one attribute binding's columns match the one-to-many attribute binding's FK columns
// (meaning this is a bidirectional association, and no back reference should be created)
List<RelationalValueBinding> valueBindings = manyToOneAttributeBinding.getRelationalValueBindings();
if ( columns.size() != valueBindings.size() ) {
if ( keyValueBindings.size() != valueBindings.size() ) {
continue;
}
bidirectional = true;
for ( int ndx = valueBindings.size(); --ndx >= 0; ) {
if ( columns.get(ndx) != valueBindings.get( ndx ).getValue() ) {
if ( keyValueBindings.get(ndx) != valueBindings.get( ndx ) ) {
bidirectional = false;
break;
}

View File

@ -153,7 +153,7 @@ public class CompositePluralAttributeIndexSourceImpl
@Override
public boolean areValuesIncludedInUpdateByDefault() {
return true;
return false;
}
@Override

View File

@ -131,7 +131,7 @@ public class SequentialPluralAttributeIndexSourceImpl extends AbstractHbmSourceN
@Override
public boolean areValuesIncludedInUpdateByDefault() {
return true;
return false;
}
@Override

View File

@ -100,6 +100,12 @@ public abstract class AbstractCompositeAttributeBindingContainer
protected abstract boolean isModifiable();
protected RelationalValueBindingContainer getRelationalValueBindingContainer() {
final RelationalValueBindingContainer bindingContainer = new RelationalValueBindingContainer();
collectRelationalValueBindings( bindingContainer );
return bindingContainer;
}
@Override
public BasicAttributeBinding makeBasicAttributeBinding(
SingularAttribute attribute,

View File

@ -48,4 +48,26 @@ public abstract class AbstractPluralAttributeElementBinding implements PluralAtt
public HibernateTypeDescriptor getHibernateTypeDescriptor() {
return hibernateTypeDescriptor;
}
protected abstract RelationalValueBindingContainer getRelationalValueContainer();
@Override
public List<RelationalValueBinding> getRelationalValueBindings() {
return getRelationalValueContainer().relationalValueBindings();
}
@Override
public boolean isNullable() {
return getRelationalValueContainer().hasNullableRelationalValueBinding();
}
@Override
public boolean hasDerivedValue() {
return getRelationalValueContainer().hasDerivedValue();
}
@Override
public boolean hasNonNullableValue() {
return getRelationalValueContainer().hasNonNullableRelationalValueBinding();
}
}

View File

@ -36,7 +36,7 @@ import org.hibernate.metamodel.spi.source.MetaAttributeContext;
/**
* @author Gail Badner
*/
public class AbstractSingularAssociationAttributeBinding extends AbstractSingularAttributeBinding
public abstract class AbstractSingularAssociationAttributeBinding extends AbstractSingularAttributeBinding
implements SingularAssociationAttributeBinding {
protected final EntityBinding referencedEntityBinding;
protected final SingularAttributeBinding referencedAttributeBinding;
@ -85,12 +85,6 @@ public class AbstractSingularAssociationAttributeBinding extends AbstractSingula
return isNotFoundAnException;
}
@Override
public boolean hasDerivedValue() {
// TODO: support derived value
return false;
}
@Override
public boolean isAssociation() {
return true;
@ -166,6 +160,6 @@ public class AbstractSingularAssociationAttributeBinding extends AbstractSingula
@Override
protected void collectRelationalValueBindings(RelationalValueBindingContainer relationalValueBindingContainer) {
relationalValueBindingContainer.addRelationalValueBindings( this.relationalValueBindingContainer);
relationalValueBindingContainer.addRelationalValueBindings( this.relationalValueBindingContainer );
}
}

View File

@ -58,9 +58,14 @@ public abstract class AbstractSingularAttributeBinding
return getRelationalValueBindingContainer().relationalValueBindings();
}
@Override
public boolean hasDerivedValue() {
return getRelationalValueBindingContainer().hasDerivedValue();
}
@Override
public boolean isNullable() {
return getRelationalValueBindingContainer().hasNullableRelationalValueBinding();
return !getRelationalValueBindingContainer().hasNonNullableRelationalValueBinding();
}
@Override

View File

@ -70,8 +70,9 @@ public class BackRefAttributeBinding extends BasicAttributeBinding {
}
else {
relationalValueBindings = new ArrayList<RelationalValueBinding>( );
for ( Column column : pluralAttributeBinding.getPluralAttributeKeyBinding().getForeignKey().getSourceColumns() ) {
relationalValueBindings.add( new RelationalValueBinding( column, true, false ) );
for ( RelationalValueBinding keyRelationalValueBindings : pluralAttributeBinding.getPluralAttributeKeyBinding().getRelationalValueBindings() ) {
Column keyColumn = (Column) keyRelationalValueBindings.getValue();
relationalValueBindings.add( new RelationalValueBinding( keyColumn, true, false ) );
}
}
return relationalValueBindings;
@ -99,18 +100,9 @@ public class BackRefAttributeBinding extends BasicAttributeBinding {
return isIndexBackRef;
}
@Override
public boolean hasDerivedValue() {
return false;
}
@Override
public boolean isNullable() {
return false;
}
@Override
public boolean isIncludedInUpdate() {
//TODO: should be able to rely on super method, but that seems broken currently.
return false;
}
}

View File

@ -23,7 +23,6 @@
*/
package org.hibernate.metamodel.spi.binding;
import java.util.Collections;
import java.util.List;
import org.hibernate.mapping.PropertyGeneration;
@ -40,7 +39,6 @@ public class BasicAttributeBinding
implements SingularNonAssociationAttributeBinding {
private final RelationalValueBindingContainer relationalValueBindingContainer;
private boolean hasDerivedValue;
private final PropertyGeneration generation;
BasicAttributeBinding(
@ -62,11 +60,7 @@ public class BasicAttributeBinding
naturalIdMutability,
metaAttributeContext
);
this.relationalValueBindingContainer =
new RelationalValueBindingContainer( relationalValueBindings );
for ( RelationalValueBinding relationalValueBinding : relationalValueBindings ) {
this.hasDerivedValue = this.hasDerivedValue || relationalValueBinding.isDerived();
}
this.relationalValueBindingContainer = new RelationalValueBindingContainer( relationalValueBindings );
this.generation = generation;
}
@ -75,15 +69,6 @@ public class BasicAttributeBinding
return false;
}
public List<RelationalValueBinding> getRelationalValueBindings() {
return relationalValueBindingContainer.relationalValueBindings();
}
@Override
public boolean hasDerivedValue() {
return hasDerivedValue;
}
public PropertyGeneration getGeneration() {
return generation;
}

View File

@ -34,29 +34,23 @@ import java.util.List;
*/
public class BasicPluralAttributeElementBinding extends AbstractPluralAttributeElementBinding {
private boolean hasDerivedValue;
private boolean isNullable = true;
private List<RelationalValueBinding> relationalValueBindings;
private RelationalValueBindingContainer relationalValueBindingContainer;
public BasicPluralAttributeElementBinding(AbstractPluralAttributeBinding binding) {
super( binding );
}
@Override
protected RelationalValueBindingContainer getRelationalValueContainer() {
return relationalValueBindingContainer;
}
@Override
public Nature getNature() {
return Nature.BASIC;
}
@Override
public List<RelationalValueBinding> getRelationalValueBindings() {
return relationalValueBindings;
}
public void setRelationalValueBindings(List<RelationalValueBinding> relationalValueBindings) {
this.relationalValueBindings = Collections.unmodifiableList( relationalValueBindings );
for ( RelationalValueBinding relationalValueBinding : getRelationalValueBindings() ) {
this.hasDerivedValue = this.hasDerivedValue || relationalValueBinding.isDerived();
this.isNullable = this.isNullable && relationalValueBinding.isNullable();
}
this.relationalValueBindingContainer = new RelationalValueBindingContainer( relationalValueBindings );
}
}

View File

@ -215,9 +215,7 @@ public class CompositeAttributeBinding
@Override
protected RelationalValueBindingContainer getRelationalValueBindingContainer() {
final RelationalValueBindingContainer relationalValueBindingContainer = new RelationalValueBindingContainer();
collectRelationalValueBindings( relationalValueBindingContainer );
return relationalValueBindingContainer;
return compositeAttributeBindingContainer.getRelationalValueBindingContainer();
}
@Override
@ -279,7 +277,6 @@ public class CompositeAttributeBinding
return true;
}
@Override
public boolean isIncludedInInsert() {
// if the attribute is synthetic, this attribute binding (as a whole) is not insertable;
@ -314,13 +311,9 @@ public class CompositeAttributeBinding
return false;
}
@Override
@Override
protected void collectRelationalValueBindings(RelationalValueBindingContainer relationalValueBindingContainer) {
for ( AttributeBinding subAttributeBinding : attributeBindings() ) {
if ( AbstractSingularAttributeBinding.class.isInstance( subAttributeBinding ) ) {
( (AbstractSingularAttributeBinding) subAttributeBinding ).collectRelationalValueBindings( relationalValueBindingContainer );
}
}
compositeAttributeBindingContainer.collectRelationalValueBindings( relationalValueBindingContainer );
}
@Override

View File

@ -23,9 +23,7 @@
*/
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.engine.spi.CascadeStyle;
@ -51,6 +49,11 @@ public class CompositePluralAttributeElementBinding
super( binding );
}
@Override
protected RelationalValueBindingContainer getRelationalValueContainer() {
return compositeAttributeBindingContainer.getRelationalValueBindingContainer();
}
@Override
public Nature getNature() {
return Nature.AGGREGATE;
@ -94,13 +97,6 @@ public class CompositePluralAttributeElementBinding
return compositeAttributeBindingContainer;
}
@Override
public List<RelationalValueBinding> getRelationalValueBindings() {
final RelationalValueBindingContainer bindingContainer = new RelationalValueBindingContainer();
compositeAttributeBindingContainer.collectRelationalValueBindings( bindingContainer );
return bindingContainer.relationalValueBindings();
}
@Override
public CascadeStyle getCascadeStyle() {
return cascadeStyle;

View File

@ -23,7 +23,6 @@
*/
package org.hibernate.metamodel.spi.binding;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -91,8 +90,6 @@ public class CompositePluralAttributeIndexBinding extends AbstractPluralAttribut
@Override
public List<RelationalValueBinding> getRelationalValueBindings() {
final RelationalValueBindingContainer bindingContainer = new RelationalValueBindingContainer();
compositeAttributeBindingContainer.collectRelationalValueBindings( bindingContainer );
return bindingContainer.relationalValueBindings();
return compositeAttributeBindingContainer.getRelationalValueBindingContainer().relationalValueBindings();
}
}

View File

@ -36,13 +36,14 @@ public class ManyToAnyPluralAttributeElementBinding extends AbstractPluralAttrib
super( binding );
}
@Override
protected RelationalValueBindingContainer getRelationalValueContainer() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public Nature getNature() {
return Nature.MANY_TO_ANY;
}
@Override
public List<RelationalValueBinding> getRelationalValueBindings() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
}

View File

@ -24,11 +24,9 @@
package org.hibernate.metamodel.spi.binding;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.hibernate.internal.FilterConfiguration;
import org.hibernate.metamodel.spi.relational.Value;
/**
* Describes plural attributes of {@link org.hibernate.metamodel.spi.binding.PluralAttributeElementBinding.Nature#MANY_TO_MANY} elements
@ -41,24 +39,24 @@ public class ManyToManyPluralAttributeElementBinding extends AbstractPluralAttri
private String manyToManyWhere;
private String manyToManyOrderBy;
// TODO: really should have value defined (which defines table), but may not know
List<RelationalValueBinding> relationalValueBindings;
private RelationalValueBindingContainer relationalValueBindingContainer;
ManyToManyPluralAttributeElementBinding(AbstractPluralAttributeBinding binding) {
super( binding );
}
@Override
protected RelationalValueBindingContainer getRelationalValueContainer() {
return relationalValueBindingContainer;
}
@Override
public Nature getNature() {
return Nature.MANY_TO_MANY;
}
@Override
public List<RelationalValueBinding> getRelationalValueBindings() {
return relationalValueBindings;
}
public void setRelationalValueBindings(List<RelationalValueBinding> relationalValueBindings) {
this.relationalValueBindings = relationalValueBindings;
this.relationalValueBindingContainer = new RelationalValueBindingContainer( relationalValueBindings );
}
public String getManyToManyWhere() {

View File

@ -33,23 +33,25 @@ import java.util.List;
*/
public class OneToManyPluralAttributeElementBinding extends AbstractPluralAttributeAssociationElementBinding {
private EntityIdentifier elementEntityIdentifier;
private RelationalValueBindingContainer relationalValueBindingContainer;
OneToManyPluralAttributeElementBinding(AbstractPluralAttributeBinding binding) {
super( binding );
}
@Override
protected RelationalValueBindingContainer getRelationalValueContainer() {
return relationalValueBindingContainer;
}
@Override
public Nature getNature() {
return Nature.ONE_TO_MANY;
}
public void setElementEntityIdentifier(EntityIdentifier elementEntityIdentifier) {
this.elementEntityIdentifier = elementEntityIdentifier;
}
@Override
public List<RelationalValueBinding> getRelationalValueBindings() {
// TODO: ugh, can't call this until after the EntityIdentifier is completely bound...
return elementEntityIdentifier.getAttributeBinding().getRelationalValueBindings();
this.relationalValueBindingContainer = new RelationalValueBindingContainer(
elementEntityIdentifier.getAttributeBinding().getRelationalValueBindings()
);
}
}

View File

@ -46,6 +46,12 @@ public interface PluralAttributeElementBinding {
*/
public List<RelationalValueBinding> getRelationalValueBindings();
public boolean isNullable();
public boolean hasDerivedValue();
public boolean hasNonNullableValue();
/**
* Retrieves an enumeration describing the mapping nature of the collection's elements.
*

View File

@ -23,9 +23,10 @@
*/
package org.hibernate.metamodel.spi.binding;
import java.util.List;
import org.hibernate.AssertionFailure;
import org.hibernate.metamodel.spi.relational.Column;
import org.hibernate.metamodel.spi.relational.ForeignKey;
import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.metamodel.spi.relational.TableSpecification;
/**
@ -36,10 +37,9 @@ import org.hibernate.metamodel.spi.relational.TableSpecification;
public class PluralAttributeKeyBinding {
private final AbstractPluralAttributeBinding pluralAttributeBinding;
private final SingularAttributeBinding referencedAttributeBinding;
private ForeignKey foreignKey;
private RelationalValueBindingContainer relationalValueBindingContainer;
private boolean isCascadeDeleteEnabled;
private boolean inverse;
private boolean insertable;
private boolean updatable;
// this knowledge can be implicitly resolved based on the typing information on the referenced owner attribute
private HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor();
@ -69,17 +69,9 @@ public class PluralAttributeKeyBinding {
return referencedAttributeBinding;
}
/**
* The foreign key that defines the scope of this relationship.
*
* @return The foreign key being bound to.
*/
public ForeignKey getForeignKey() {
return foreignKey;
}
public TableSpecification getCollectionTable() {
return foreignKey.getSourceTable();
// TODO: get table directly from relationalValueBindingContainer
return relationalValueBindingContainer.relationalValueBindings().get( 0 ).getValue().getTable();
}
/**
@ -105,48 +97,47 @@ public class PluralAttributeKeyBinding {
this.hibernateTypeDescriptor = hibernateTypeDescriptor;
}
public void setForeignKey(ForeignKey foreignKey) {
if ( foreignKey == null ) {
throw new AssertionFailure( "foreignKey argument must be non-null." );
public List<RelationalValueBinding> getRelationalValueBindings() {
return relationalValueBindingContainer.relationalValueBindings();
}
public void setRelationalValueBindings(List<RelationalValueBinding> relationalValueBindings) {
if ( relationalValueBindings == null || relationalValueBindings.isEmpty() ) {
throw new AssertionFailure( "relationalValueBindings argument must be non-null and non-empty." );
}
if ( this.foreignKey != null ) {
throw new AssertionFailure( "Foreign key already initialized" );
if ( this.relationalValueBindingContainer != null ) {
throw new AssertionFailure( "Relational value bindings have already initialized" );
}
this.foreignKey = foreignKey;
this.relationalValueBindingContainer = new RelationalValueBindingContainer( relationalValueBindings );
if ( this.relationalValueBindingContainer.hasDerivedValue() ) {
throw new NotYetImplementedException(
"Derived values are not supported when creating a foreign key that targets columns."
);
}
}
public boolean isCascadeDeleteEnabled() {
return isCascadeDeleteEnabled;
}
public void setCascadeDeleteEnabled(boolean isCascadeDeleteEnabled) {
this.isCascadeDeleteEnabled = isCascadeDeleteEnabled;
}
public boolean isNullable() {
if ( foreignKey == null || foreignKey.getSourceColumns().isEmpty() ) {
throw new IllegalStateException( "Foreign key has no columns." );
}
// cannot be nullable if the foreign key source columns are included in the primary key .
if ( foreignKey.getTable().getPrimaryKey().getColumns().containsAll( foreignKey.getSourceColumns() ) ) {
// cannot be nullable if the foreign key source columns are included in the primary key
// TODO: move this into RelationalValueBindingContainer.
if ( getCollectionTable().getPrimaryKey().getColumns().containsAll( relationalValueBindingContainer.columns() ) ) {
return false;
}
for ( Column column : foreignKey.getSourceColumns() ) {
if ( column.isNullable() ) {
return true;
}
}
return false;
}
public void setInsertable( boolean insertable ){
this.insertable = insertable;
return relationalValueBindingContainer.hasNullableRelationalValueBinding();
}
public boolean isInsertable() {
return insertable;
}
public void setUpdatable( boolean updatable ){
// The key is updatable if the foreign key *source* columns are updatable;
// We don't have the RelationalValueBindings for the FK source columns stored in ForeignKey
// so it needs to be set explicitly.
this.updatable = updatable;
return relationalValueBindingContainer.hasInsertableRelationalValueBinding();
}
public boolean isUpdatable() {
return updatable;
return relationalValueBindingContainer.hasUpdateableRelationalValueBinding();
}
}

View File

@ -43,7 +43,6 @@ public class RelationalValueBindingContainer {
this.isListModifiable = false;
}
public RelationalValueBindingContainer() {
this.relationalValueBindings = new ArrayList<RelationalValueBinding>();
this.isListModifiable = true;
@ -81,11 +80,12 @@ public class RelationalValueBindingContainer {
}
public boolean hasDerivedValue() {
boolean hasDerivedValue = false;
for ( RelationalValueBinding relationalValueBinding : relationalValueBindings ) {
hasDerivedValue = hasDerivedValue || relationalValueBinding.isDerived();
if (relationalValueBinding.isDerived() ) {
return true;
}
}
return hasDerivedValue;
return false;
}
public boolean hasNullableRelationalValueBinding() {
@ -123,35 +123,4 @@ public class RelationalValueBindingContainer {
}
return false;
}
/*
protected static boolean hasNullableRelationalValueBinding(List<RelationalValueBinding> relationalValueBindings) {
for ( RelationalValueBinding relationalValueBinding : relationalValueBindings ) {
if ( relationalValueBinding.isNullable() ) {
return true;
}
}
return false;
}
protected static boolean hasInsertableRelationalValueBinding(List<RelationalValueBinding> relationalValueBindings) {
for ( RelationalValueBinding relationalValueBinding : relationalValueBindings ) {
if ( relationalValueBinding.isIncludeInInsert() ) {
return true;
}
}
return false;
}
protected static boolean hasUpdateableRelationalValueBinding(List<RelationalValueBinding> relationalValueBindings) {
for ( RelationalValueBinding relationalValueBinding : relationalValueBindings ) {
if ( relationalValueBinding.isIncludeInUpdate() ) {
return true;
}
}
return false;
}
*/
}
}

View File

@ -746,11 +746,12 @@ public abstract class AbstractCollectionPersister
PluralAttributeKeyBinding keyBinding = collection.getPluralAttributeKeyBinding();
keyType = keyBinding.getHibernateTypeDescriptor().getResolvedTypeMapping();
int keySpan = keyBinding.getForeignKey().getColumnSpan();
int keySpan = keyBinding.getRelationalValueBindings().size();
keyColumnNames = new String[keySpan];
keyColumnAliases = new String[keySpan];
int k = 0;
for ( Column keyColumn : keyBinding.getForeignKey().getSourceColumns() ) {
for ( RelationalValueBinding keyRelationalValueBinding : keyBinding.getRelationalValueBindings() ) {
Column keyColumn = (Column) keyRelationalValueBinding.getValue();
// NativeSQL: collect key column and auto-aliases
keyColumnNames[k] = keyColumn.getColumnName().getText( dialect );
// TODO: does the owner root table need to be in alias?

View File

@ -110,8 +110,7 @@ public class OneToManyPersister extends AbstractCollectionPersister {
);
}
final PluralAttributeKeyBinding keyBinding = collection.getPluralAttributeKeyBinding();
cascadeDeleteEnabled = keyBinding.getForeignKey().getDeleteRule() == ForeignKey.ReferentialAction.CASCADE &&
factory.getDialect().supportsCascadeDelete();;
cascadeDeleteEnabled = keyBinding.isCascadeDeleteEnabled() && factory.getDialect().supportsCascadeDelete();
keyIsNullable = keyBinding.isNullable();
keyIsUpdateable = keyBinding.isUpdatable();
}

View File

@ -24,6 +24,7 @@
package org.hibernate.metamodel.spi.binding.basiccollections;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import org.junit.After;
@ -45,6 +46,7 @@ import org.hibernate.metamodel.spi.binding.PluralAttributeKeyBinding;
import org.hibernate.metamodel.spi.binding.RelationalValueBinding;
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
import org.hibernate.metamodel.spi.domain.PluralAttribute;
import org.hibernate.metamodel.spi.relational.Column;
import org.hibernate.metamodel.spi.relational.ForeignKey;
import org.hibernate.metamodel.spi.relational.Identifier;
import org.hibernate.metamodel.spi.relational.TableSpecification;
@ -174,24 +176,19 @@ public abstract class AbstractBasicCollectionBindingTests extends BaseUnitTestCa
assertEquals( expectedFetchTiming, collectionBinding.getFetchTiming() );
assertEquals( expectedFetchTiming != FetchTiming.IMMEDIATE, collectionBinding.isLazy() );
ForeignKey fk = keyBinding.getForeignKey();
assertNotNull( fk );
assertSame( collectionTable, fk.getSourceTable() );
assertEquals( 1, fk.getColumnSpan() );
List<RelationalValueBinding> keyRelationalValueBindings = keyBinding.getRelationalValueBindings();
assertNotNull( keyRelationalValueBindings );
for( RelationalValueBinding keyRelationalValueBinding : keyRelationalValueBindings ) {
assertSame( collectionTable, keyRelationalValueBinding.getValue().getTable() );
}
assertEquals( 1, keyRelationalValueBindings.size() );
assertEquals( 1, expectedKeyTargetAttributeBinding.getRelationalValueBindings().size() );
Value expectedFKTargetValue = expectedKeyTargetAttributeBinding.getRelationalValueBindings().get( 0 ).getValue();
assertEquals( fk.getColumns(), fk.getSourceColumns() );
assertEquals( 1, fk.getSourceColumns().size() );
assertEquals( 1, fk.getTargetColumns().size() );
assertEquals( expectedKeySourceColumnName, fk.getSourceColumns().get( 0 ).getColumnName() );
assertSame( expectedFKTargetValue, fk.getTargetColumns().get( 0 ) );
assertSame( collectionOwnerBinding.getPrimaryTable(), fk.getTargetTable() );
assertEquals( expectedFKTargetValue.getJdbcDataType(), fk.getSourceColumns().get( 0 ).getJdbcDataType() );
assertFalse( keyRelationalValueBindings.get( 0 ).isDerived() );
assertEquals( expectedKeySourceColumnName, ( (Column) keyRelationalValueBindings.get( 0 ).getValue() ).getColumnName() );
assertEquals( expectedFKTargetValue.getJdbcDataType(), keyRelationalValueBindings.get( 0 ).getValue().getJdbcDataType() );
assertSame( ForeignKey.ReferentialAction.NO_ACTION, fk.getDeleteRule() );
assertSame( ForeignKey.ReferentialAction.NO_ACTION, fk.getUpdateRule() );
// FK name is null because no default FK name is generated until HHH-7092 is fixed
assertNull( fk.getName() );
assertFalse( keyBinding.isCascadeDeleteEnabled() );
checkEquals(
expectedKeyTargetAttributeBinding.getHibernateTypeDescriptor(),
keyBinding.getHibernateTypeDescriptor()
@ -222,7 +219,7 @@ public abstract class AbstractBasicCollectionBindingTests extends BaseUnitTestCa
}
else {
assertEquals( 2, collectionTable.getPrimaryKey().getColumnSpan() );
assertSame( fk.getSourceColumns().get( 0 ), collectionTable.getPrimaryKey().getColumns().get( 0 ) );
assertSame( keyRelationalValueBindings.get( 0 ).getValue(), collectionTable.getPrimaryKey().getColumns().get( 0 ) );
assertSame( elementRelationalValueBinding.getValue(), collectionTable.getPrimaryKey().getColumns().get( 1 ) );
}
}

View File

@ -43,6 +43,7 @@ import org.hibernate.metamodel.spi.binding.HibernateTypeDescriptor;
import org.hibernate.metamodel.spi.binding.PluralAttributeBinding;
import org.hibernate.metamodel.spi.binding.PluralAttributeElementBinding;
import org.hibernate.metamodel.spi.binding.PluralAttributeKeyBinding;
import org.hibernate.metamodel.spi.binding.RelationalValueBinding;
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
import org.hibernate.metamodel.spi.relational.Column;
import org.hibernate.metamodel.spi.relational.ForeignKey;
@ -202,18 +203,12 @@ public abstract class AbstractUnidirectionalOneToManyBindingTests extends BaseUn
expectedCollectionTypeClass.cast( collectionHibernateTypeDescriptor.getResolvedTypeMapping() ).getRole()
);
ForeignKey fk = keyBinding.getForeignKey();
assertNotNull( fk );
assertSame( ForeignKey.ReferentialAction.NO_ACTION, fk.getDeleteRule() );
assertSame( ForeignKey.ReferentialAction.NO_ACTION, fk.getUpdateRule() );
// FK name is null because no default FK name is generated until HHH-7092 is fixed
assertNull( fk.getName() );
List<RelationalValueBinding> keyRelationalValueBinding = keyBinding.getRelationalValueBindings();
assertNotNull( keyRelationalValueBinding );
assertFalse( keyBinding.isCascadeDeleteEnabled() );
assertSame( expectedElementEntityBinding.getPrimaryTable(), fk.getSourceTable() );
assertEquals( 1, fk.getColumnSpan() );
assertEquals( fk.getColumns(), fk.getSourceColumns() );
assertEquals( 1, fk.getSourceColumns().size() );
assertEquals( 1, fk.getTargetColumns().size() );
assertSame( expectedElementEntityBinding.getPrimaryTable(), keyBinding.getCollectionTable() );
assertEquals( 1, keyRelationalValueBinding.size() );
SingularAttributeBinding keySourceAttributeBinding =
( SingularAttributeBinding ) expectedElementEntityBinding.locateAttributeBinding(
@ -229,19 +224,12 @@ public abstract class AbstractUnidirectionalOneToManyBindingTests extends BaseUn
assertTrue( keySourceValue instanceof Column );
Column keySourceColumn = ( Column ) keySourceValue;
assertEquals( expectedKeySourceColumnName, keySourceColumn.getColumnName() );
assertSame( keySourceColumn, fk.getColumns().get( 0 ) );
assertSame( keySourceColumn, fk.getSourceColumns().get( 0 ) );
}
assertSame( collectionOwnerBinding.getPrimaryTable(), fk.getTargetTable() );
assertEquals( 1, expectedKeyTargetAttributeBinding.getRelationalValueBindings().size() );
assertSame(
expectedKeyTargetAttributeBinding.getRelationalValueBindings().get( 0 ).getValue(),
fk.getTargetColumns().get( 0 )
);
assertEquals(
expectedKeyTargetAttributeBinding.getRelationalValueBindings().get( 0 ).getValue().getJdbcDataType(),
fk.getColumns().get( 0 ).getJdbcDataType()
keyRelationalValueBinding.get( 0 ).getValue().getJdbcDataType()
);
checkEquals(

View File

@ -33,7 +33,6 @@ import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
/**
* @author Emmanuel Bernard
*/
@FailureExpectedWithNewMetamodel
public class UnidirCollectionWithMultipleOwnerTest extends BaseCoreFunctionalTestCase {
@Test
public void testUnidirCollectionWithMultipleOwner() throws Exception {

View File

@ -28,7 +28,6 @@ import org.junit.Test;
import org.hibernate.Session;
import org.hibernate.collection.internal.PersistentMap;
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.junit.Assert.assertEquals;