From af891c09970002e57cef43ac18375fe1b6cd79ac Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Thu, 1 Apr 2021 06:54:57 -0500 Subject: [PATCH] re-enable tests re-organize some tests clean-up and tests related to fks --- .../AbstractCompositeIdentifierMapping.java | 2 +- .../mapping/EmbeddableMappingType.java | 4 +- .../mapping/ForeignKeyDescriptor.java | 14 +- .../metamodel/mapping/ModelPart.java | 4 +- .../metamodel/mapping/SelectableMappings.java | 5 +- .../EmbeddedForeignKeyDescriptor.java | 57 ++-- .../internal/EntityCollectionPart.java | 39 ++- .../internal/MappingModelCreationHelper.java | 23 +- .../internal/PluralAttributeMappingImpl.java | 2 +- .../internal/SimpleForeignKeyDescriptor.java | 193 ++++++++--- .../internal/SingleSelectableMappings.java | 3 +- .../internal/ToOneAttributeMapping.java | 2 +- .../internal/cte/CteDeleteHandler.java | 2 +- .../sql/ast/spi/SqlAliasBaseImpl.java | 5 + .../NonRootTablePolymorphicTests.java | 307 ++++++++++++++++++ .../manytoone/ManyToOneJoinTableTest.java | 8 +- .../test/mapping/manytoone/ManyToOneTest.java | 2 +- ...ntityWithBidirectionalAssociationTest.java | 4 +- ...BidirectionalJoinTableAssociationTest.java | 4 +- .../EntityWithOneToOneJoinTableTest.java | 2 +- ...tityWithOneToOneSharingPrimaryKeyTest.java | 2 +- 21 files changed, 559 insertions(+), 125 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/constraint/NonRootTablePolymorphicTests.java diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractCompositeIdentifierMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractCompositeIdentifierMapping.java index 1eb6d1173d..307109792f 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractCompositeIdentifierMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractCompositeIdentifierMapping.java @@ -124,7 +124,7 @@ public abstract class AbstractCompositeIdentifierMapping final SingularAttributeMapping attribute = attributes.get( i ); if ( attribute instanceof ToOneAttributeMapping ) { final ToOneAttributeMapping associationAttributeMapping = (ToOneAttributeMapping) attribute; - span += associationAttributeMapping.getForeignKeyDescriptor().visitReferringSelectables( + span += associationAttributeMapping.getForeignKeyDescriptor().visitKeySelectables( span + offset, consumer ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EmbeddableMappingType.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EmbeddableMappingType.java index 82cd169f34..a43d2a96b5 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EmbeddableMappingType.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EmbeddableMappingType.java @@ -594,8 +594,8 @@ public class EmbeddableMappingType implements ManagedMappingType, SelectableMapp } @Override - public void forEachSelectable(SelectableConsumer consumer) { - selectableMappings.forEachSelectable( 0, consumer ); + public int forEachSelectable(SelectableConsumer consumer) { + return selectableMappings.forEachSelectable( 0, consumer ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ForeignKeyDescriptor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ForeignKeyDescriptor.java index 76cd082e0c..dcf1f0755a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ForeignKeyDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ForeignKeyDescriptor.java @@ -18,14 +18,14 @@ import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.DomainResultCreationState; /** - * @author Steve Ebersole + * Descriptor for foreign-keys */ public interface ForeignKeyDescriptor extends VirtualModelPart { String PART_NAME = "{fk}"; - String getKeyColumnContainingTable(); + String getKeyTable(); - String getTargetColumnContainingTable(); + String getTargetTable(); DomainResult createCollectionFetchDomainResult( NavigablePath collectionPath, @@ -67,15 +67,15 @@ public interface ForeignKeyDescriptor extends VirtualModelPart { */ @Override default int forEachSelectable(int offset, SelectableConsumer consumer) { - return visitReferringSelectables( offset, consumer ); + return visitKeySelectables( offset, consumer ); } Object getAssociationKeyFromTarget(Object targetObject, SharedSessionContractImplementor session); - int visitReferringSelectables(int offset, SelectableConsumer consumer); + int visitKeySelectables(int offset, SelectableConsumer consumer); - default int visitReferringSelectables(SelectableConsumer consumer) { - return visitReferringSelectables( 0, consumer ); + default int visitKeySelectables(SelectableConsumer consumer) { + return visitKeySelectables( 0, consumer ); } int visitTargetSelectables(int offset, SelectableConsumer consumer); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ModelPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ModelPart.java index 9f2245eafc..d2530fef5e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ModelPart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ModelPart.java @@ -96,8 +96,8 @@ public interface ModelPart extends MappingModelExpressable { throw new NotYetImplementedFor6Exception( getClass() ); } - default void forEachSelectable(SelectableConsumer consumer) { - forEachSelectable( 0, consumer ); + default int forEachSelectable(SelectableConsumer consumer) { + return forEachSelectable( 0, consumer ); } default int forEachSelectable(int offset, SelectableConsumer consumer) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/SelectableMappings.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/SelectableMappings.java index 497cad3b19..92475f9a33 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/SelectableMappings.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/SelectableMappings.java @@ -40,9 +40,10 @@ public interface SelectableMappings { /** * Same as {@link #forEachSelectable(int, SelectableConsumer)}, with * an implicit offset of `0` + * @return */ - default void forEachSelectable(SelectableConsumer consumer) { - forEachSelectable( 0, consumer ); + default int forEachSelectable(SelectableConsumer consumer) { + return forEachSelectable( 0, consumer ); } /** diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedForeignKeyDescriptor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedForeignKeyDescriptor.java index ebd6c879b0..d89311d3c5 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedForeignKeyDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedForeignKeyDescriptor.java @@ -19,7 +19,6 @@ import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.MappingType; -import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.SelectableConsumer; import org.hibernate.metamodel.mapping.SelectableMappings; import org.hibernate.metamodel.model.domain.NavigableRole; @@ -46,25 +45,25 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor; /** * @author Andrea Boriero */ -public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, ModelPart { +public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor { private final EmbeddableValuedModelPart mappingType; - private final String keyColumnContainingTable; + private final String keyTable; private final SelectableMappings keySelectableMappings; - private final String targetColumnContainingTable; + private final String targetTable; private final SelectableMappings targetSelectableMappings; private AssociationKey associationKey; public EmbeddedForeignKeyDescriptor( EmbeddableValuedModelPart mappingType, - String keyColumnContainingTable, + String keyTable, SelectableMappings keySelectableMappings, - String targetColumnContainingTable, + String targetTable, SelectableMappings targetSelectableMappings, MappingModelCreationProcess creationProcess) { - this.keyColumnContainingTable = keyColumnContainingTable; + this.keyTable = keyTable; this.keySelectableMappings = keySelectableMappings; - this.targetColumnContainingTable = targetColumnContainingTable; + this.targetTable = targetTable; this.targetSelectableMappings = targetSelectableMappings; this.mappingType = mappingType; @@ -85,13 +84,13 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model } @Override - public String getKeyColumnContainingTable() { - return keyColumnContainingTable; + public String getKeyTable() { + return keyTable; } @Override - public String getTargetColumnContainingTable() { - return targetColumnContainingTable; + public String getTargetTable() { + return targetTable; } @Override @@ -99,11 +98,11 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model NavigablePath collectionPath, TableGroup tableGroup, DomainResultCreationState creationState) { - if ( targetColumnContainingTable.equals( keyColumnContainingTable ) ) { + if ( targetTable.equals( keyTable ) ) { return createDomainResult( collectionPath, tableGroup, - targetColumnContainingTable, + targetTable, targetSelectableMappings, creationState ); @@ -112,7 +111,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model return createDomainResult( collectionPath, tableGroup, - keyColumnContainingTable, + keyTable, keySelectableMappings, creationState ); @@ -127,7 +126,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model return createDomainResult( collectionPath, tableGroup, - keyColumnContainingTable, + keyTable, keySelectableMappings, creationState ); @@ -143,7 +142,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model return createDomainResult( collectionPath, tableGroup, - keyColumnContainingTable, + keyTable, keySelectableMappings, creationState ); @@ -152,7 +151,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model return createDomainResult( collectionPath, tableGroup, - targetColumnContainingTable, + targetTable, targetSelectableMappings, creationState ); @@ -213,22 +212,22 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model SqlAstCreationContext creationContext) { TableReference lhsTableReference; TableReference rhsTableKeyReference; - if ( targetColumnContainingTable.equals( keyColumnContainingTable ) ) { - lhsTableReference = getTableReferenceWhenTargetEqualsKey( lhs, tableGroup, keyColumnContainingTable ); + if ( targetTable.equals( keyTable ) ) { + lhsTableReference = getTableReferenceWhenTargetEqualsKey( lhs, tableGroup, keyTable ); rhsTableKeyReference = getTableReference( lhs, tableGroup, - targetColumnContainingTable + targetTable ); } else { - lhsTableReference = getTableReference( lhs, tableGroup, keyColumnContainingTable ); + lhsTableReference = getTableReference( lhs, tableGroup, keyTable ); rhsTableKeyReference = getTableReference( lhs, tableGroup, - targetColumnContainingTable + targetTable ); } @@ -250,12 +249,12 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model SqlAstCreationContext creationContext) { final String rhsTableExpression = rhs.getTableExpression(); final String lhsTableExpression = lhs.getTableExpression(); - if ( lhsTableExpression.equals( keyColumnContainingTable ) ) { - assert rhsTableExpression.equals( targetColumnContainingTable ); + if ( lhsTableExpression.equals( keyTable ) ) { + assert rhsTableExpression.equals( targetTable ); return getPredicate( lhs, rhs, creationContext, keySelectableMappings, targetSelectableMappings ); } else { - assert rhsTableExpression.equals( keyColumnContainingTable ); + assert rhsTableExpression.equals( keyTable ); return getPredicate( lhs, rhs, creationContext, targetSelectableMappings, keySelectableMappings ); } } @@ -322,7 +321,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model } @Override - public int visitReferringSelectables(int offset, SelectableConsumer consumer) { + public int visitKeySelectables(int offset, SelectableConsumer consumer) { return keySelectableMappings.forEachSelectable( offset, consumer ); } @@ -340,7 +339,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model columns.add( selection.getSelectionExpression() ); } ); - associationKey = new AssociationKey( keyColumnContainingTable, columns ); + associationKey = new AssociationKey( keyTable, columns ); } return associationKey; } @@ -369,7 +368,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model //noinspection unchecked final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState(); final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver(); - final TableReference tableReference = tableGroup.resolveTableReference( keyColumnContainingTable ); + final TableReference tableReference = tableGroup.resolveTableReference( keyTable ); final String identificationVariable = tableReference.getIdentificationVariable(); final int size = keySelectableMappings.getJdbcTypeCount(); final List sqlSelections = new ArrayList<>( size ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityCollectionPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityCollectionPart.java index 48ea558844..3c60f84712 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityCollectionPart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityCollectionPart.java @@ -222,8 +222,43 @@ public class EntityCollectionPart // // // todo (6.0) : do we need to make the FK table/columns available as well from this table group? // -// final TableReference fkReferringTable = parentTableGroup.resolveTableReference( foreignKeyDescriptor.getKeyColumnContainingTable() ); -// final TableReference fkTargetTable = entityTableGroup.resolveTableReference( foreignKeyDescriptor.getTargetColumnContainingTable() ); +// final TableReference fkReferringTable; +// try { +// fkReferringTable = parentTableGroup.resolveTableReference( foreignKeyDescriptor.getKeyTable() ); +// } +// catch (HibernateException e) { +// throw e; +// } +// catch (Exception e) { +// throw new SqlTreeCreationException( +// String.format( +// Locale.ROOT, +// "Unable to locate `%s` as foreign-key referring table for entity collection part `%s` relative to parent TableGroup : %s", +// foreignKeyDescriptor.getKeyTable(), +// navigableRole.getFullPath(), +// parentTableGroup +// ) +// ); +// } +// +// final TableReference fkTargetTable; +// try { +// fkTargetTable = entityTableGroup.resolveTableReference( foreignKeyDescriptor.getTargetTable() ); +// } +// catch (HibernateException e) { +// throw e; +// } +// catch (Exception e) { +// throw new SqlTreeCreationException( +// String.format( +// Locale.ROOT, +// "Unable to locate `%s` as foreign-key target table for entity collection part `%s` relative to rhs TableGroup : %s", +// foreignKeyDescriptor.getTargetTable(), +// navigableRole.getFullPath(), +// entityTableGroup +// ) +// ); +// } // // return new TableGroupJoin( // navigablePath, diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java index 00804d0743..5e227b9634 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java @@ -923,7 +923,7 @@ public class MappingModelCreationHelper { new SimpleForeignKeyDescriptor( keySelectableMapping, simpleFkTarget, - ( (PropertyBasedMapping) simpleFkTarget ).getPropertyAccess(), + (owner) -> ( (PropertyBasedMapping) simpleFkTarget ).getPropertyAccess().getGetter().get( owner ), isReferenceToPrimaryKey ) ); @@ -946,17 +946,19 @@ public class MappingModelCreationHelper { } } - public static void interpretSingularAssociationAttributeMappingKeyDescriptor( + public static void interpretToOneKeyDescriptor( ToOneAttributeMapping attributeMapping, Property bootProperty, ToOne bootValueMapping, Dialect dialect, MappingModelCreationProcess creationProcess) { if ( attributeMapping.getForeignKeyDescriptor() != null ) { + // already built/known return; } final String tableName = getTableIdentifierExpression( bootValueMapping.getTable(), creationProcess ); + attributeMapping.setIdentifyingColumnsTableExpression( tableName ); final EntityPersister referencedEntityDescriptor = creationProcess @@ -998,7 +1000,7 @@ public class MappingModelCreationHelper { } else { throw new NotYetImplementedFor6Exception( - "Support for composite foreign-keys not yet implemented: " + + "Support for foreign-keys based on `" + modelPart + "` not yet implemented: " + bootProperty.getPersistentClass().getEntityName() + " -> " + bootProperty.getName() ); } @@ -1047,7 +1049,7 @@ public class MappingModelCreationHelper { final ForeignKeyDescriptor foreignKeyDescriptor = new SimpleForeignKeyDescriptor( keySelectableMapping, simpleFkTarget, - ( (PropertyBasedMapping) simpleFkTarget ).getPropertyAccess(), + (owner) -> ( (PropertyBasedMapping) simpleFkTarget ).getPropertyAccess().getGetter().get( owner ), bootValueMapping.isReferenceToPrimaryKey() ); attributeMapping.setForeignKeyDescriptor( foreignKeyDescriptor ); @@ -1154,7 +1156,7 @@ public class MappingModelCreationHelper { .getEntityBinding( referencedEntityDescriptor.getEntityName() ); Property property = entityBinding.getProperty( referencedPropertyName ); - interpretSingularAssociationAttributeMappingKeyDescriptor( + interpretToOneKeyDescriptor( referencedAttributeMapping, property, (ToOne) property.getValue(), @@ -1173,11 +1175,10 @@ public class MappingModelCreationHelper { .getMetadata() .getDatabase() .getJdbcEnvironment(); - return jdbcEnvironment - .getQualifiedObjectNameFormatter().format( - table.getQualifiedTableName(), - jdbcEnvironment.getDialect() - ); + return jdbcEnvironment.getQualifiedObjectNameFormatter().format( + table.getQualifiedTableName(), + jdbcEnvironment.getDialect() + ); } private static CollectionPart interpretMapKey( @@ -1469,7 +1470,7 @@ public class MappingModelCreationHelper { .getJdbcServices() .getDialect(); - MappingModelCreationHelper.interpretSingularAssociationAttributeMappingKeyDescriptor( + MappingModelCreationHelper.interpretToOneKeyDescriptor( attributeMapping, bootProperty, (ToOne) bootProperty.getValue(), diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/PluralAttributeMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/PluralAttributeMappingImpl.java index b9e8b13dea..16acdbc529 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/PluralAttributeMappingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/PluralAttributeMappingImpl.java @@ -341,7 +341,7 @@ public class PluralAttributeMappingImpl return new SimpleForeignKeyDescriptor( keySelectableMapping, basicFkTargetPart, - ( (PropertyBasedMapping) basicFkTargetPart ).getPropertyAccess(), + (owner) -> ( (PropertyBasedMapping) basicFkTargetPart ).getPropertyAccess().getGetter().get( owner ), entityType.isReferenceToPrimaryKey() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleForeignKeyDescriptor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleForeignKeyDescriptor.java index 3b37893c6d..dbfbad609f 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleForeignKeyDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleForeignKeyDescriptor.java @@ -8,25 +8,31 @@ package org.hibernate.metamodel.mapping.internal; import java.util.Collections; import java.util.List; +import java.util.function.Function; import org.hibernate.LockMode; +import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.engine.FetchStyle; import org.hibernate.engine.FetchTiming; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.mapping.IndexedConsumer; import org.hibernate.metamodel.mapping.AssociationKey; +import org.hibernate.metamodel.mapping.BasicValuedMapping; import org.hibernate.metamodel.mapping.BasicValuedModelPart; -import org.hibernate.metamodel.mapping.SelectableConsumer; -import org.hibernate.metamodel.mapping.SelectableMapping; import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; import org.hibernate.metamodel.mapping.JdbcMapping; +import org.hibernate.metamodel.mapping.MappingModelExpressable; import org.hibernate.metamodel.mapping.MappingType; +import org.hibernate.metamodel.mapping.SelectableConsumer; +import org.hibernate.metamodel.mapping.SelectableMapping; +import org.hibernate.metamodel.mapping.SelectableMappings; +import org.hibernate.metamodel.mapping.ValueMapping; import org.hibernate.metamodel.model.domain.NavigableRole; -import org.hibernate.property.access.spi.PropertyAccess; import org.hibernate.proxy.HibernateProxy; import org.hibernate.query.ComparisonOperator; import org.hibernate.query.NavigablePath; +import org.hibernate.query.sqm.sql.internal.DomainResultProducer; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstJoinType; import org.hibernate.sql.ast.spi.SqlAstCreationContext; @@ -51,31 +57,46 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor; * @author Steve Ebersole */ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicValuedModelPart, FetchOptions { - private final SelectableMapping keySelectableMapping; - private final SelectableMapping targetSelectableMapping; - private final PropertyAccess propertyAccess; + private final SideModelPart keySide; + private final SideModelPart targetSide; + private final boolean refersToPrimaryKey; + + private final Function disassemblyValueExtractor; + private AssociationKey associationKey; public SimpleForeignKeyDescriptor( SelectableMapping keySelectableMapping, SelectableMapping targetSelectableMapping, - PropertyAccess propertyAccess, + Function disassemblyValueExtractor, boolean refersToPrimaryKey) { - this.keySelectableMapping = keySelectableMapping; - this.targetSelectableMapping = targetSelectableMapping; - this.propertyAccess = propertyAccess; + assert keySelectableMapping != null; + assert targetSelectableMapping != null; + assert disassemblyValueExtractor != null; + + this.keySide = new SideModelPart( keySelectableMapping ); + this.targetSide = new SideModelPart( targetSelectableMapping ); + this.disassemblyValueExtractor = disassemblyValueExtractor; this.refersToPrimaryKey = refersToPrimaryKey; } @Override - public String getKeyColumnContainingTable() { - return keySelectableMapping.getContainingTableExpression(); + public String getKeyTable() { + return keySide.selectableMapping.getContainingTableExpression(); } @Override - public String getTargetColumnContainingTable() { - return targetSelectableMapping.getContainingTableExpression(); + public String getTargetTable() { + return targetSide.selectableMapping.getContainingTableExpression(); + } + + public SideModelPart getKeySide() { + return keySide; + } + + public SideModelPart getTargetSide() { + return targetSide; } @Override @@ -83,31 +104,31 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa NavigablePath collectionPath, TableGroup tableGroup, DomainResultCreationState creationState) { - if ( targetSelectableMapping.getContainingTableExpression() - .equals( keySelectableMapping.getContainingTableExpression() ) ) { - return createDomainResult( tableGroup, targetSelectableMapping, creationState ); + if ( targetSide.selectableMapping.getContainingTableExpression() + .equals( keySide.selectableMapping.getContainingTableExpression() ) ) { + return createDomainResult( tableGroup, targetSide.selectableMapping, creationState ); } return createDomainResult( collectionPath, tableGroup, creationState ); } @Override - public DomainResult createDomainResult( + public DomainResult createDomainResult( NavigablePath navigablePath, TableGroup tableGroup, DomainResultCreationState creationState) { - return createDomainResult( tableGroup, keySelectableMapping, creationState ); + return createDomainResult( tableGroup, keySide.selectableMapping, creationState ); } @Override - public DomainResult createDomainResult( + public DomainResult createDomainResult( NavigablePath navigablePath, TableGroup tableGroup, boolean isKeyReferringSide, DomainResultCreationState creationState) { if ( isKeyReferringSide ) { - return createDomainResult( tableGroup, keySelectableMapping, creationState ); + return createDomainResult( tableGroup, keySide.selectableMapping, creationState ); } - return createDomainResult( tableGroup, targetSelectableMapping, creationState ); + return createDomainResult( tableGroup, targetSide.selectableMapping, creationState ); } @Override @@ -116,7 +137,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa TableGroup tableGroup, String resultVariable, DomainResultCreationState creationState) { - return createDomainResult( tableGroup, keySelectableMapping, creationState ); + return createDomainResult( tableGroup, keySide.selectableMapping, creationState ); } private DomainResult createDomainResult( @@ -145,7 +166,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa ); //noinspection unchecked - return new BasicResult( + return new BasicResult( sqlSelection.getValuesArrayPosition(), null, selectableMapping.getJdbcMapping().getJavaTypeDescriptor() @@ -159,17 +180,17 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa SqlAstJoinType sqlAstJoinType, SqlExpressionResolver sqlExpressionResolver, SqlAstCreationContext creationContext) { - if ( lhs.getTableReference( keySelectableMapping.getContainingTableExpression() ) != null ) { + if ( lhs.getTableReference( keySide.selectableMapping.getContainingTableExpression() ) != null ) { return new ComparisonPredicate( new ColumnReference( lhs, - keySelectableMapping, + keySide.selectableMapping, creationContext.getSessionFactory() ), ComparisonOperator.EQUAL, new ColumnReference( rhs, - targetSelectableMapping, + targetSide.selectableMapping, creationContext.getSessionFactory() ) ); @@ -178,13 +199,13 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa return new ComparisonPredicate( new ColumnReference( lhs, - targetSelectableMapping, + targetSide.selectableMapping, creationContext.getSessionFactory() ), ComparisonOperator.EQUAL, new ColumnReference( rhs, - keySelectableMapping, + keySide.selectableMapping, creationContext.getSessionFactory() ) ); @@ -200,22 +221,22 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa SqlAstCreationContext creationContext) { TableReference lhsTableReference; TableReference rhsTableKeyReference; - if ( targetSelectableMapping.getContainingTableExpression().equals( keySelectableMapping.getContainingTableExpression() ) ) { - lhsTableReference = getTableReferenceWhenTargetEqualsKey( lhs, tableGroup, keySelectableMapping.getContainingTableExpression() ); + if ( targetSide.selectableMapping.getContainingTableExpression().equals( keySide.selectableMapping.getContainingTableExpression() ) ) { + lhsTableReference = getTableReferenceWhenTargetEqualsKey( lhs, tableGroup, keySide.selectableMapping.getContainingTableExpression() ); rhsTableKeyReference = getTableReference( lhs, tableGroup, - targetSelectableMapping.getContainingTableExpression() + targetSide.selectableMapping.getContainingTableExpression() ); } else { - lhsTableReference = getTableReference( lhs, tableGroup, keySelectableMapping.getContainingTableExpression() ); + lhsTableReference = getTableReference( lhs, tableGroup, keySide.selectableMapping.getContainingTableExpression() ); rhsTableKeyReference = getTableReference( lhs, tableGroup, - targetSelectableMapping.getContainingTableExpression() + targetSide.selectableMapping.getContainingTableExpression() ); } @@ -263,7 +284,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa @Override public JavaTypeDescriptor getJavaTypeDescriptor() { - return targetSelectableMapping.getJdbcMapping().getJavaTypeDescriptor(); + return targetSide.getJdbcMapping().getJavaTypeDescriptor(); } @Override @@ -284,7 +305,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa if ( refersToPrimaryKey && value instanceof HibernateProxy ) { return ( (HibernateProxy) value ).getHibernateLazyInitializer().getIdentifier(); } - return propertyAccess.getGetter().get( value ); + return disassemblyValueExtractor.apply( value ); } @Override @@ -305,38 +326,38 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa @Override public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { - valueConsumer.consume( domainValue, keySelectableMapping ); + valueConsumer.consume( domainValue, keySide.selectableMapping ); } @Override - public int visitReferringSelectables(int offset, SelectableConsumer consumer) { - consumer.accept( offset, keySelectableMapping ); + public int visitKeySelectables(int offset, SelectableConsumer consumer) { + consumer.accept( offset, keySide.selectableMapping ); return getJdbcTypeCount(); } @Override public int visitTargetSelectables(int offset, SelectableConsumer consumer) { - consumer.accept( offset, targetSelectableMapping ); + consumer.accept( offset, targetSide.selectableMapping ); return getJdbcTypeCount(); } @Override public AssociationKey getAssociationKey() { if ( associationKey == null ) { - final List associationKeyColumns = Collections.singletonList( keySelectableMapping.getSelectionExpression() ); - associationKey = new AssociationKey( keySelectableMapping.getContainingTableExpression(), associationKeyColumns ); + final List associationKeyColumns = Collections.singletonList( keySide.selectableMapping.getSelectionExpression() ); + associationKey = new AssociationKey( keySide.selectableMapping.getContainingTableExpression(), associationKeyColumns ); } return associationKey; } @Override public List getJdbcMappings() { - return Collections.singletonList( targetSelectableMapping.getJdbcMapping() ); + return Collections.singletonList( targetSide.getJdbcMapping() ); } @Override public int forEachJdbcType(int offset, IndexedConsumer action) { - action.accept( offset, targetSelectableMapping.getJdbcMapping() ); + action.accept( offset, targetSide.getJdbcMapping() ); return getJdbcTypeCount(); } @@ -347,34 +368,34 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa int offset, JdbcValuesConsumer valuesConsumer, SharedSessionContractImplementor session) { - valuesConsumer.consume( offset, value, targetSelectableMapping.getJdbcMapping() ); + valuesConsumer.consume( offset, value, targetSide.getJdbcMapping() ); return getJdbcTypeCount(); } @Override public String getContainingTableExpression() { - return keySelectableMapping.getContainingTableExpression(); + return keySide.selectableMapping.getContainingTableExpression(); } @Override public String getSelectionExpression() { - return keySelectableMapping.getSelectionExpression(); + return keySide.selectableMapping.getSelectionExpression(); } @Override public boolean isFormula() { - return keySelectableMapping.isFormula(); + return keySide.selectableMapping.isFormula(); } @Override public String getCustomReadExpression() { - return keySelectableMapping.getCustomReadExpression(); + return keySide.selectableMapping.getCustomReadExpression(); } @Override public String getCustomWriteExpression() { - return keySelectableMapping.getCustomWriteExpression(); + return keySide.selectableMapping.getCustomWriteExpression(); } @Override @@ -416,13 +437,77 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa @Override public JdbcMapping getJdbcMapping() { - return keySelectableMapping.getJdbcMapping(); + return keySide.getJdbcMapping(); } @Override public String toString() { - return "SimpleForeignKeyDescriptor : " + keySelectableMapping.getContainingTableExpression() + "." + keySelectableMapping - .getSelectionExpression() - + " --> " + targetSelectableMapping.getContainingTableExpression() + "." + targetSelectableMapping.getSelectionExpression(); + return String.format( + "SimpleForeignKeyDescriptor : %s.%s -> %s.%s", + keySide.selectableMapping.getContainingTableExpression(), + keySide.selectableMapping.getSelectionExpression(), + targetSide.selectableMapping.getContainingTableExpression(), + targetSide.selectableMapping.getSelectionExpression() + ); + } + + private interface KeySideModelPart extends MappingModelExpressable, DomainResultProducer, SelectableMappings { + @Override + default int getJdbcTypeCount() { + throw new NotYetImplementedFor6Exception( getClass() ); + } + + @Override + default List getJdbcMappings() { + throw new NotYetImplementedFor6Exception( getClass() ); + } + } + + public static class SideModelPart implements BasicValuedMapping, KeySideModelPart { + private final SelectableMapping selectableMapping; + private final List jdbcMappings; + + public SideModelPart(SelectableMapping selectableMapping) { + assert selectableMapping != null; + this.selectableMapping = selectableMapping; + + this.jdbcMappings = Collections.singletonList( getJdbcMapping() ); + } + + public SelectableMapping getSelectableMapping() { + return selectableMapping; + } + + @Override + public int getJdbcTypeCount() { + return 1; + } + + @Override + public List getJdbcMappings() { + return jdbcMappings; + } + + @Override + public JdbcMapping getJdbcMapping() { + return selectableMapping.getJdbcMapping(); + } + + @Override + public MappingType getMappedType() { + return getJdbcMapping(); + } + + @Override + public SelectableMapping getSelectable(int columnIndex) { + assert columnIndex == 0; + return selectableMapping; + } + + @Override + public int forEachSelectable(int offset, SelectableConsumer consumer) { + consumer.accept( offset, selectableMapping ); + return 1; + } } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SingleSelectableMappings.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SingleSelectableMappings.java index 25e32b8ca5..71bba43b4c 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SingleSelectableMappings.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SingleSelectableMappings.java @@ -87,8 +87,9 @@ public class SingleSelectableMappings implements SelectableMapping, SelectableMa } @Override - public void forEachSelectable(SelectableConsumer consumer) { + public int forEachSelectable(SelectableConsumer consumer) { consumer.accept( 0, this ); + return 1; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java index c8a13a22d1..6533b887cb 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java @@ -669,7 +669,7 @@ public class ToOneAttributeMapping @Override public int forEachSelectable(int offset, SelectableConsumer consumer) { if ( isKeyReferringSide ) { - return foreignKeyDescriptor.visitReferringSelectables( offset, consumer ); + return foreignKeyDescriptor.visitKeySelectables( offset, consumer ); } else { return 0; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteDeleteHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteDeleteHandler.java index eb37fec0a0..6d7d53ced7 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteDeleteHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteDeleteHandler.java @@ -74,7 +74,7 @@ public class CteDeleteHandler extends AbstractCteMutationHandler implements Dele ); final TableReference dmlTableReference = new TableReference( tableExpression, null, true, factory ); final List columnReferences = new ArrayList<>( idSelectCte.getCteTable().getCteColumns().size() ); - pluralAttribute.getKeyDescriptor().visitReferringSelectables( + pluralAttribute.getKeyDescriptor().visitKeySelectables( (index, selectable) -> columnReferences.add( new ColumnReference( dmlTableReference, diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAliasBaseImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAliasBaseImpl.java index 1896631d79..2e50b79dfe 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAliasBaseImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAliasBaseImpl.java @@ -36,4 +36,9 @@ public class SqlAliasBaseImpl implements SqlAliasBase { return alias; } } + + @Override + public String toString() { + return "SqlAliasBase(" + stem + " : " + aliasCount + ")"; + } } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/constraint/NonRootTablePolymorphicTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/constraint/NonRootTablePolymorphicTests.java new file mode 100644 index 0000000000..dab20568e2 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/constraint/NonRootTablePolymorphicTests.java @@ -0,0 +1,307 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.orm.test.constraint; + +import java.util.Iterator; +import java.util.List; +import javax.persistence.CollectionTable; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.Table; + +import org.hibernate.mapping.Column; +import org.hibernate.mapping.ForeignKey; +import org.hibernate.mapping.JoinedSubclass; +import org.hibernate.mapping.PersistentClass; +import org.hibernate.mapping.PrimaryKey; +import org.hibernate.mapping.Property; +import org.hibernate.mapping.Selectable; +import org.hibernate.mapping.Subclass; +import org.hibernate.mapping.ToOne; +import org.hibernate.metamodel.mapping.AttributeMapping; +import org.hibernate.metamodel.mapping.EntityMappingType; +import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; +import org.hibernate.metamodel.mapping.internal.SimpleForeignKeyDescriptor; +import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.hamcrest.CollectionMatchers; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.DomainModelScope; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.Matchers.anyOf; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.Matchers.sameInstance; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + +/** + * Simplified form of mappings from {@link ForeignKeyNoConstraintTest} + * specifically for checking definition of foreign-keys related + * to non-root tables within a joined-hierarchy. + * + * It tries to get to the bottom of the failures in + * {@link ForeignKeyConstraintTest#testGet} + */ +@TestForIssue( jiraKey = "HHH-11180" ) +@DomainModel( + annotatedClasses = { + NonRootTablePolymorphicTests.Root.class, + NonRootTablePolymorphicTests.Sub.class, + NonRootTablePolymorphicTests.Leaf.class, + NonRootTablePolymorphicTests.SubParent.class, + NonRootTablePolymorphicTests.SubChild.class, + NonRootTablePolymorphicTests.SubGroup.class, + } +) +@SessionFactory +public class NonRootTablePolymorphicTests { + @Test + public void verifyBootModel(DomainModelScope scope) { + // check the foreign-keys within the joined-hierarchy + scope.withHierarchy( + Root.class, + (root) -> { + final org.hibernate.mapping.Table rootRootTable = root.getRootTable(); + final org.hibernate.mapping.Table rootTable = root.getTable(); + assertThat( rootRootTable, sameInstance( rootTable ) ); + assertThat( rootRootTable.getName(), is( "root" ) ); + + final Iterator subclassIterator = root.getSubclassIterator(); + while ( subclassIterator.hasNext() ) { + final JoinedSubclass subclass = (JoinedSubclass) subclassIterator.next(); + final org.hibernate.mapping.Table subclassTable = subclass.getTable(); + + if ( subclass.getJpaEntityName().equals( "Sub" ) ) { + assertThat( subclass.getRootTable(), sameInstance( rootTable ) ); + assertThat( subclassTable, not( sameInstance( rootTable ) ) ); + assertThat( subclassTable.getName(), is( "sub" ) ); + + final PrimaryKey primaryKey = subclassTable.getPrimaryKey(); + assertThat( primaryKey.getColumnSpan(), is( 1 ) ); + assertThat( primaryKey.getColumn( 0 ).getName(), is( "sub_id" ) ); + + // the sub table should have 2 foreign-keys defined: + // 1) for the sub->root inheritance fk + // 2) for the sub->child fk + + assertThat( subclassTable.getForeignKeys().size(), is( 2 ) ); + subclassTable.getForeignKeyIterator().forEachRemaining( + (foreignKey) -> { + assertThat( foreignKey.getTable(), sameInstance( subclassTable ) ); + + // see which we have... + if ( foreignKey.getReferencedTable().getName().equals( "root" ) ) { + assertThat( foreignKey.getReferencedTable(), sameInstance( rootTable ) ); + + assertThat( foreignKey.getColumns().get( 0 ).getName(), is( "sub_id" ) ); + + // this is how the boot model represents an fk pointing to the pk.. + assertThat( + foreignKey.getReferencedColumns(), + anyOf( + nullValue(), + CollectionMatchers.isEmpty() + ) + ); + } + else if ( foreignKey.getReferencedTable().getName().equals( "sub_child" ) ) { + assertThat( foreignKey.getColumns().get( 0 ).getName(), is( "child_fk" ) ); + + // this is how the boot model represents an fk pointing to the pk.. + assertThat( + foreignKey.getReferencedColumns(), + anyOf( + nullValue(), + CollectionMatchers.isEmpty() + ) + ); + } + else { + fail( "Unexpected fk reference from `sub` to `" + foreignKey.getReferencedTable().getName() + "`" ); + } + } + ); + } + else if ( subclass.getJpaEntityName().equals( "Leaf" ) ) { + assertThat( subclass.getRootTable(), sameInstance( rootTable ) ); + assertThat( subclassTable, not( sameInstance( rootTable ) ) ); + assertThat( subclassTable.getName(), is( "leaf" ) ); + + final PrimaryKey primaryKey = subclassTable.getPrimaryKey(); + assertThat( primaryKey.getColumnSpan(), is( 1 ) ); + assertThat( primaryKey.getColumn( 0 ).getName(), is( "leaf_id" ) ); + } + } + } + ); + + // check the association *to* the joined-hierarchy (aka, SubParent#sub) + // - we already checked the association *from* earlier + scope.withHierarchy( + SubParent.class, + (subParent) -> { + final Property subProperty = subParent.getProperty( "sub" ); + final ToOne toOne = (ToOne) subProperty.getValue(); + + assertThat( toOne.getTable().getName(), is( "sub_parent" ) ); + + assertThat( toOne.getColumnSpan(), is( 1 ) ); + final Selectable selectable = toOne.getColumnIterator().next(); + assertThat( selectable.getText(), is( "parent_sub_fk" ) ); + + assertThat( subParent.getTable().getForeignKeys().size(), is( 1 ) ); + final ForeignKey foreignKey = subParent.getTable().getForeignKeyIterator().next(); + + assertThat( foreignKey.getReferencedTable().getName(), is( "sub" ) ); + assertThat( foreignKey.getTable(), sameInstance( toOne.getTable() ) ); + } + ); + } + + + @Test + public void verifyRuntimeModel(SessionFactoryScope scope) { + final EntityMappingType rootEntity = scope.getSessionFactory() + .getRuntimeMetamodels() + .getEntityMappingType( Root.class ); + final EntityMappingType subEntity = scope.getSessionFactory() + .getRuntimeMetamodels() + .getEntityMappingType( Sub.class ); + final EntityMappingType leafEntity = scope.getSessionFactory() + .getRuntimeMetamodels() + .getEntityMappingType( Leaf.class ); + final EntityMappingType childEntity = scope.getSessionFactory() + .getRuntimeMetamodels() + .getEntityMappingType( SubChild.class ); + final EntityMappingType parentEntity = scope.getSessionFactory() + .getRuntimeMetamodels() + .getEntityMappingType( SubParent.class ); + + + // check Sub#child fk + + final ToOneAttributeMapping childAttribute = (ToOneAttributeMapping) subEntity.findAttributeMapping( "child" ); + final SimpleForeignKeyDescriptor childFk = (SimpleForeignKeyDescriptor) childAttribute.getForeignKeyDescriptor(); + + assertThat( childFk.getKeyTable(), is( "sub" ) ); + assertThat( childFk.getTargetTable(), is( "sub_child" ) ); + + assertThat( childFk.getJdbcTypeCount(), is( 1 ) ); + assertThat( childFk.getKeySide().getSelectableMapping().getSelectionExpression(), is( "child_fk" ) ); + assertThat( childFk.getTargetSide().getSelectableMapping().getSelectionExpression(), is( "child_id" ) ); + + + // check Parent#sub fk + + final ToOneAttributeMapping subAttribute = (ToOneAttributeMapping) parentEntity.findAttributeMapping( "sub" ); + final SimpleForeignKeyDescriptor subFk = (SimpleForeignKeyDescriptor) subAttribute.getForeignKeyDescriptor(); + + assertThat( subFk.getKeyTable(), is( "sub_parent" ) ); + assertThat( subFk.getTargetTable(), is( "sub" ) ); + + assertThat( subFk.getJdbcTypeCount(), is( 1 ) ); + assertThat( subFk.getKeySide().getSelectableMapping().getSelectionExpression(), is( "parent_sub_fk" ) ); + assertThat( subFk.getTargetSide().getSelectableMapping().getSelectionExpression(), is( "sub_id" ) ); + + scope.inTransaction( + (session) -> { + session.createQuery( "from SubParent p join fetch p.sub" ).list(); + session.createQuery( "from SubGroup p join fetch p.manyToManySubs" ).list(); + session.createQuery( "from SubGroup p join fetch p.oneToManySubs" ).list(); + } + ); + + // for sure the inheritance keys are messed up in the mapping model + } + + @Entity( name = "Root" ) + @Table( name = "root" ) + @Inheritance( strategy = InheritanceType.JOINED ) + public static class Root { + @Id + @javax.persistence.Column( name = "root_id" ) + private Integer id; + private String name; + } + + @Entity( name = "Sub" ) + @Table( name = "sub" ) + @PrimaryKeyJoinColumn( name = "sub_id", referencedColumnName = "root_id" ) + public static class Sub extends Root { + private String subText; + + @ManyToOne + @JoinColumn( name = "child_fk", referencedColumnName = "child_id" ) + public SubChild child; + } + + @Entity( name = "Leaf" ) + @Table( name = "leaf" ) + @PrimaryKeyJoinColumn( name = "leaf_id", referencedColumnName = "root_id" ) + public static class Leaf extends Root { + private String teaLeaves; + } + + + @Entity( name = "SubParent" ) + @Table( name = "sub_parent" ) + public static class SubParent { + @Id + @javax.persistence.Column( name = "parent_id" ) + private Integer id; + private String name; + @ManyToOne + @JoinColumn( name = "parent_sub_fk", referencedColumnName = "sub_id" ) + public Sub sub; + } + + + @Entity( name = "SubChild" ) + @Table( name = "sub_child" ) + public static class SubChild { + @Id + @javax.persistence.Column( name = "child_id" ) + private Integer id; + private String name; + } + + @Entity( name = "SubGroup" ) + @Table( name = "sub_group" ) + public static class SubGroup { + @Id + @javax.persistence.Column( name = "group_id" ) + private Integer id; + private String name; + + @ManyToMany + @JoinTable( + name = "m2m_group", + joinColumns = @JoinColumn( name = "m2m_group_fk", referencedColumnName = "group_id" ), + inverseJoinColumns = @JoinColumn( name = "m2m_sub_fk", referencedColumnName = "sub_id" ) + ) + private List manyToManySubs; + + @OneToMany + @PrimaryKeyJoinColumn( name = "m_group_fk", referencedColumnName = "group_id" ) + private List oneToManySubs; + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/manytoone/ManyToOneJoinTableTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/manytoone/ManyToOneJoinTableTest.java index 81b918b066..21af6f22fd 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/manytoone/ManyToOneJoinTableTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/manytoone/ManyToOneJoinTableTest.java @@ -56,7 +56,7 @@ public class ManyToOneJoinTableTest { final ToOneAttributeMapping simpleAttributeMapping = (ToOneAttributeMapping) simpleEntityAssociation; ForeignKeyDescriptor foreignKeyDescriptor = simpleAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringSelectables( + foreignKeyDescriptor.visitKeySelectables( (columnIndex, selection) -> { assertThat( selection.getContainingTableExpression(), is( "other_simple" ) ); assertThat( selection.getSelectionExpression(), is( "RHS_ID" ) ); @@ -77,7 +77,7 @@ public class ManyToOneJoinTableTest { final ToOneAttributeMapping anotherAttributeMapping = (ToOneAttributeMapping) anotherEntityAssociation; foreignKeyDescriptor = anotherAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringSelectables( + foreignKeyDescriptor.visitKeySelectables( (columnIndex, selection) -> { assertThat( selection.getContainingTableExpression(), is( "other_another" ) ); assertThat( selection.getSelectionExpression(), is( "RHS_ID" ) ); @@ -103,7 +103,7 @@ public class ManyToOneJoinTableTest { ToOneAttributeMapping otherAttributeMapping = (ToOneAttributeMapping) otherEntityEntityAssociation; foreignKeyDescriptor = otherAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringSelectables( + foreignKeyDescriptor.visitKeySelectables( (columnIndex, selection) -> { assertThat( selection.getContainingTableExpression(), is( "other_simple" ) ); assertThat( selection.getSelectionExpression(), is( "LHS_ID" ) ); @@ -129,7 +129,7 @@ public class ManyToOneJoinTableTest { otherAttributeMapping = (ToOneAttributeMapping) otherEntityEntityAssociation; foreignKeyDescriptor = otherAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringSelectables( + foreignKeyDescriptor.visitKeySelectables( (columnIndex, selection) -> { assertThat( selection.getContainingTableExpression(), is( "another_entity" ) ); assertThat( selection.getSelectionExpression(), is( "other_id" ) ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/manytoone/ManyToOneTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/manytoone/ManyToOneTest.java index 68b4f21009..0f5c29582b 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/manytoone/ManyToOneTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/manytoone/ManyToOneTest.java @@ -53,7 +53,7 @@ public class ManyToOneTest { final ToOneAttributeMapping childAttributeMapping = (ToOneAttributeMapping) simpleEntityAssociation; ForeignKeyDescriptor foreignKeyDescriptor = childAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringSelectables( + foreignKeyDescriptor.visitKeySelectables( (columnIndex, selection) -> { assertThat( selection.getContainingTableExpression(), is( "other_entity" ) ); assertThat( selection.getSelectionExpression(), is( "simple_entity_id" ) ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetoone/EntityWithBidirectionalAssociationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetoone/EntityWithBidirectionalAssociationTest.java index b5635442f6..b2d754af89 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetoone/EntityWithBidirectionalAssociationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetoone/EntityWithBidirectionalAssociationTest.java @@ -51,7 +51,7 @@ public class EntityWithBidirectionalAssociationTest { final ToOneAttributeMapping childAttributeMapping = (ToOneAttributeMapping) childAssociation; ForeignKeyDescriptor foreignKeyDescriptor = childAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringSelectables( + foreignKeyDescriptor.visitKeySelectables( (columnIndex, selection) -> { assertThat( selection.getContainingTableExpression(), is( "PARENT" ) ); assertThat( selection.getSelectionExpression(), is( "child_id" ) ); @@ -76,7 +76,7 @@ public class EntityWithBidirectionalAssociationTest { final ToOneAttributeMapping parentAttributeMapping = (ToOneAttributeMapping) parentAssociation; foreignKeyDescriptor = parentAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringSelectables( + foreignKeyDescriptor.visitKeySelectables( (columnIndex, selection) -> { assertThat( selection.getContainingTableExpression(), is( "PARENT" ) ); assertThat( selection.getSelectionExpression(), is( "child_id" ) ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetoone/EntityWithOneBidirectionalJoinTableAssociationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetoone/EntityWithOneBidirectionalJoinTableAssociationTest.java index e31616a03d..b5b6b8fe61 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetoone/EntityWithOneBidirectionalJoinTableAssociationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetoone/EntityWithOneBidirectionalJoinTableAssociationTest.java @@ -53,7 +53,7 @@ public class EntityWithOneBidirectionalJoinTableAssociationTest { final ToOneAttributeMapping childAttributeMapping = (ToOneAttributeMapping) childAssociation; ForeignKeyDescriptor foreignKeyDescriptor = childAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringSelectables( + foreignKeyDescriptor.visitKeySelectables( (columnIndex, selection) -> { assertThat( selection.getContainingTableExpression(), is( "PARENT_CHILD" ) ); assertThat( selection.getSelectionExpression(), is( "child_id" ) ); @@ -78,7 +78,7 @@ public class EntityWithOneBidirectionalJoinTableAssociationTest { final ToOneAttributeMapping parentAttributeMapping = (ToOneAttributeMapping) parentAssociation; foreignKeyDescriptor = parentAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringSelectables( + foreignKeyDescriptor.visitKeySelectables( (columnIndex, selection) -> { assertThat( selection.getContainingTableExpression(), is( "PARENT_CHILD" ) ); assertThat( selection.getSelectionExpression(), is( "parent_id" ) ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetoone/EntityWithOneToOneJoinTableTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetoone/EntityWithOneToOneJoinTableTest.java index 96243c51e9..07b3c49cd3 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetoone/EntityWithOneToOneJoinTableTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetoone/EntityWithOneToOneJoinTableTest.java @@ -47,7 +47,7 @@ public class EntityWithOneToOneJoinTableTest { final ToOneAttributeMapping otherAttributeMapping = (ToOneAttributeMapping) other; final ForeignKeyDescriptor foreignKeyDescriptor = otherAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringSelectables( + foreignKeyDescriptor.visitKeySelectables( (columnIndex, selection) -> { assertThat( selection.getContainingTableExpression(), is( "Entity_SimpleEntity" ) ); assertThat( selection.getSelectionExpression(), is( "other_id" ) ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetoone/EntityWithOneToOneSharingPrimaryKeyTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetoone/EntityWithOneToOneSharingPrimaryKeyTest.java index ec2b236f38..981c939865 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetoone/EntityWithOneToOneSharingPrimaryKeyTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/onetoone/EntityWithOneToOneSharingPrimaryKeyTest.java @@ -48,7 +48,7 @@ public class EntityWithOneToOneSharingPrimaryKeyTest { final ToOneAttributeMapping otherAttributeMapping = (ToOneAttributeMapping) otherAssociation; ForeignKeyDescriptor foreignKeyDescriptor = otherAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringSelectables( + foreignKeyDescriptor.visitKeySelectables( (columnIndex, selection) -> { assertThat( selection.getContainingTableExpression(), is( "EntityWithOneToOneSharingPrimaryKey" ) ); assertThat( selection.getSelectionExpression(), is( "id" ) );