diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/Association.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/Association.java index d5a3fb3589..9de82f2057 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/Association.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/Association.java @@ -13,10 +13,4 @@ import org.hibernate.sql.results.graph.Fetchable; */ public interface Association extends Fetchable { ForeignKeyDescriptor getForeignKeyDescriptor(); - - /** - * The column expressions that identify this association. - * Mainly used in circularity detection - */ - String[] getIdentifyingColumnExpressions(); } 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 bbd092bb39..42e9678e9b 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 @@ -47,7 +47,6 @@ public class EntityCollectionPart private final EntityMappingType entityMappingType; private ModelPart fkTargetModelPart; - private String[] identifyingColumns; @SuppressWarnings("WeakerAccess") public EntityCollectionPart( @@ -75,14 +74,6 @@ public class EntityCollectionPart else { fkTargetModelPart = entityMappingType.findSubPart( fkTargetModelPartName, null ); } - - final List identifyingColumnsList = new ArrayList<>(); - collectionDescriptor.getAttributeMapping().getKeyDescriptor().visitReferringColumns( - (containingTableExpression, columnExpression, jdbcMapping) -> { - identifyingColumnsList.add( containingTableExpression + "." + columnExpression ); - } - ); - this.identifyingColumns = identifyingColumnsList.toArray( new String[0] ); } @@ -212,9 +203,4 @@ public class EntityCollectionPart // todo (6.0) : this will not strictly work - we'd want a new ForeignKeyDescriptor that points the other direction return collectionDescriptor.getAttributeMapping().getKeyDescriptor(); } - - @Override - public String[] getIdentifyingColumnExpressions() { - return identifyingColumns; - } } 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 cfe7e73088..9bdb28a3b0 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,6 +8,7 @@ package org.hibernate.metamodel.mapping.internal; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.function.Consumer; import org.hibernate.HibernateException; @@ -57,6 +58,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa private final String targetColumnExpression; private final JdbcMapping jdbcMapping; private final ForeignKeyDirection fKeyDirection; + private final int hasCode; public SimpleForeignKeyDescriptor( ForeignKeyDirection fKeyDirection, @@ -71,6 +73,13 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa this.targetColumnContainingTable = targetColumnContainingTable; this.targetColumnExpression = targetColumnExpression; this.jdbcMapping = jdbcMapping; + + this.hasCode = Objects.hash( + keyColumnContainingTable, + keyColumnExpression, + targetColumnContainingTable, + targetColumnExpression + ); } @Override @@ -405,4 +414,24 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa public String getTargetColumnExpression() { return targetColumnExpression; } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + SimpleForeignKeyDescriptor that = (SimpleForeignKeyDescriptor) o; + return Objects.equals( keyColumnContainingTable, that.keyColumnContainingTable ) && + Objects.equals( targetColumnContainingTable, that.targetColumnContainingTable ) && + Objects.equals( keyColumnExpression, that.keyColumnExpression ) && + Objects.equals( targetColumnExpression, that.targetColumnExpression ); + } + + @Override + public int hashCode() { + return this.hasCode; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SingularAssociationAttributeMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SingularAssociationAttributeMapping.java index 5c0ddb9031..e61f88456a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SingularAssociationAttributeMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SingularAssociationAttributeMapping.java @@ -6,10 +6,6 @@ */ package org.hibernate.metamodel.mapping.internal; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - import org.hibernate.HibernateException; import org.hibernate.LockMode; import org.hibernate.NotYetImplementedFor6Exception; @@ -81,11 +77,6 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu private ForeignKeyDescriptor foreignKeyDescriptor; private String identifyingColumnsTableExpression; - private String inverseIdentifyingColumnsTableExpression; - private String[] identifyingColumns; - - - public SingularAssociationAttributeMapping( String name, @@ -139,30 +130,14 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu this.foreignKeyDescriptor = foreignKeyDescriptor; final String identifyingColumnsTableExpression; - final String inverseColumnsTableExpression; - final List identifyingColumnsList = new ArrayList<>(); if ( foreignKeyDescriptor.getDirection() == ForeignKeyDirection.FROM_PARENT && !referringPrimaryKey ) { identifyingColumnsTableExpression = foreignKeyDescriptor.getTargetTableExpression(); - inverseColumnsTableExpression = foreignKeyDescriptor.getReferringTableExpression(); - foreignKeyDescriptor.visitTargetColumns( - (containingTableExpression, columnExpression, jdbcMapping) -> { - identifyingColumnsList.add( containingTableExpression + "." + columnExpression ); - } - ); } else { identifyingColumnsTableExpression = foreignKeyDescriptor.getReferringTableExpression(); - inverseColumnsTableExpression = foreignKeyDescriptor.getTargetTableExpression(); - foreignKeyDescriptor.visitReferringColumns( - (containingTableExpression, columnExpression, jdbcMapping) -> { - identifyingColumnsList.add( containingTableExpression + "." + columnExpression ); - } - ); } - this.identifyingColumns = identifyingColumnsList.toArray( new String[0] ); this.identifyingColumnsTableExpression = identifyingColumnsTableExpression; - this.inverseIdentifyingColumnsTableExpression = inverseColumnsTableExpression; } public ForeignKeyDescriptor getForeignKeyDescriptor() { @@ -188,11 +163,6 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu return navigableRole; } - @Override - public String[] getIdentifyingColumnExpressions() { - return identifyingColumns; - } - @Override public Fetch resolveCircularFetch( NavigablePath fetchablePath, @@ -218,7 +188,7 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu final Association associationParent = (Association) referencedModePart; - if ( Arrays.equals( associationParent.getIdentifyingColumnExpressions(), this.getIdentifyingColumnExpressions() ) ) { + if (foreignKeyDescriptor.equals( associationParent.getForeignKeyDescriptor() ) ) { // we need to determine the NavigablePath referring to the entity that the bi-dir // fetch will "return" for its Assembler. so we walk "up" the FetchParent graph // to find the "referenced entity" reference diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/Helper.java b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/Helper.java index 03cb2bd324..8e6fb06b6b 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/Helper.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/Helper.java @@ -52,14 +52,22 @@ public class Helper { if ( ResultsLogger.INSTANCE.isDebugEnabled() ) { return initializer -> { ResultsLogger.INSTANCE.debug( "Adding initializer : " + initializer ); - initializers.add( initializer ); + addIfNotPresent( initializers, initializer ); }; } else { - return initializers::add; + return initializer -> + addIfNotPresent( initializers, initializer ); } } + private static void addIfNotPresent(List initializers, Initializer initializer) { + if ( initializers.contains( initializer ) ) { + return; + } + initializers.add( initializer ); + } + public static void finalizeCollectionLoading( PersistenceContext persistenceContext, CollectionPersister collectionDescriptor, diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/domain/BiDirectionalFetchImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/domain/BiDirectionalFetchImpl.java index 59d58501d2..0c82a9301e 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/domain/BiDirectionalFetchImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/domain/BiDirectionalFetchImpl.java @@ -155,13 +155,6 @@ public class BiDirectionalFetchImpl implements BiDirectionalFetch, Association { return ( (Association) fetchParent ).getForeignKeyDescriptor(); } - @Override - public String[] getIdentifyingColumnExpressions() { - // fetch parent really always needs to be an Association, so we simply cast here - // should maybe verify this in ctor - return ( (Association) fetchParent ).getIdentifyingColumnExpressions(); - } - @Override public Fetch generateFetch( FetchParent fetchParent,