From dcbef8705c09d10f4b066384765bd4470427dd00 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Tue, 10 Dec 2019 14:13:41 -0600 Subject: [PATCH] HHH-13769: Avoid unnecessary joins better support for lazy TableReference handling for collections --- .../metamodel/mapping/CollectionPart.java | 7 - .../internal/BasicValuedCollectionPart.java | 16 +- .../CollectionIdentifierDescriptorImpl.java | 13 +- .../internal/EmbeddedCollectionPart.java | 8 - .../internal/EntityCollectionPart.java | 51 +-- .../internal/MappingModelCreationHelper.java | 107 +++-- .../internal/MappingModelCreationProcess.java | 5 + .../internal/PluralAttributeMappingImpl.java | 369 ++++++++++++++---- .../SingularAssociationAttributeMapping.java | 34 +- .../AbstractCollectionPersister.java | 67 +--- .../collection/BasicCollectionPersister.java | 8 + .../collection/OneToManyPersister.java | 43 ++ .../entity/AbstractEntityPersister.java | 34 +- .../idtable/ExecuteWithIdTableHelper.java | 1 - .../idtable/ExecuteWithoutIdTableHelper.java | 1 - .../hibernate/sql/ast/tree/cte/CteTable.java | 1 - .../sql/ast/tree/from/StandardTableGroup.java | 23 +- .../sql/ast/tree/from/TableGroupBuilder.java | 139 ------- 18 files changed, 477 insertions(+), 450 deletions(-) delete mode 100644 hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupBuilder.java diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/CollectionPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/CollectionPart.java index 412bd34dc0..4a07a2de86 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/CollectionPart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/CollectionPart.java @@ -6,11 +6,6 @@ */ package org.hibernate.metamodel.mapping; -import org.hibernate.sql.ast.spi.SqlAliasBase; -import org.hibernate.sql.ast.spi.SqlAstCreationContext; -import org.hibernate.sql.ast.spi.SqlExpressionResolver; -import org.hibernate.sql.ast.tree.from.TableGroupBuilder; -import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.results.graph.Fetchable; /** @@ -67,6 +62,4 @@ public interface CollectionPart extends ModelPart, Fetchable { default String getPartName() { return getNature().getName(); } - - void applyPrimaryTableReference(TableGroupBuilder tableGroupBuilder, SqlExpressionResolver sqlExpressionResolver, SqlAstCreationContext creationContext); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicValuedCollectionPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicValuedCollectionPart.java index b4ea417b4b..2f24a40d53 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicValuedCollectionPart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicValuedCollectionPart.java @@ -19,21 +19,17 @@ import org.hibernate.metamodel.mapping.MappingType; import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.query.NavigablePath; -import org.hibernate.sql.ast.spi.SqlAliasBase; -import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.sql.ast.tree.from.TableGroupBuilder; -import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.results.ResultsLogger; -import org.hibernate.sql.results.graph.basic.BasicFetch; -import org.hibernate.sql.results.graph.basic.BasicResult; import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.Fetch; import org.hibernate.sql.results.graph.FetchParent; +import org.hibernate.sql.results.graph.basic.BasicFetch; +import org.hibernate.sql.results.graph.basic.BasicResult; import org.hibernate.type.BasicType; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.spi.TypeConfiguration; @@ -78,14 +74,6 @@ public class BasicValuedCollectionPart implements CollectionPart, BasicValuedMod return mapper; } - @Override - public void applyPrimaryTableReference( - TableGroupBuilder tableGroupBuilder, - SqlExpressionResolver sqlExpressionResolver, - SqlAstCreationContext creationContext) { - // nothing to do - } - @Override public String getContainingTableExpression() { return tableExpression; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CollectionIdentifierDescriptorImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CollectionIdentifierDescriptorImpl.java index 8e034f6888..7742b09d5f 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CollectionIdentifierDescriptorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CollectionIdentifierDescriptorImpl.java @@ -23,13 +23,12 @@ import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.sql.ast.tree.from.TableGroupBuilder; -import org.hibernate.sql.results.graph.basic.BasicFetch; -import org.hibernate.sql.results.graph.basic.BasicResult; import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.Fetch; import org.hibernate.sql.results.graph.FetchParent; +import org.hibernate.sql.results.graph.basic.BasicFetch; +import org.hibernate.sql.results.graph.basic.BasicResult; import org.hibernate.type.BasicType; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; @@ -78,14 +77,6 @@ public class CollectionIdentifierDescriptorImpl implements CollectionIdentifierD return type; } - @Override - public void applyPrimaryTableReference( - TableGroupBuilder tableGroupBuilder, - SqlExpressionResolver sqlExpressionResolver, - SqlAstCreationContext creationContext) { - // nothing to do - } - @Override public JdbcMapping getJdbcMapping() { return type; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedCollectionPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedCollectionPart.java index be602a1209..de6fb5a4d0 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedCollectionPart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedCollectionPart.java @@ -34,7 +34,6 @@ import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.SqlTuple; import org.hibernate.sql.ast.tree.from.CompositeTableGroup; import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.sql.ast.tree.from.TableGroupBuilder; import org.hibernate.sql.ast.tree.from.TableGroupJoin; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.TableReferenceCollector; @@ -198,13 +197,6 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF // nothing to do } - @Override - public void applyPrimaryTableReference( - TableGroupBuilder tableGroupBuilder, - SqlExpressionResolver sqlExpressionResolver, - SqlAstCreationContext creationContext) { - } - @Override public TableReference createPrimaryTableReference( SqlAliasBase sqlAliasBase, 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 edeac86d60..7bdf55d996 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 @@ -10,22 +10,16 @@ import org.hibernate.LockMode; import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.engine.FetchStrategy; import org.hibernate.engine.FetchTiming; +import org.hibernate.mapping.Collection; import org.hibernate.mapping.Value; import org.hibernate.metamodel.mapping.CollectionPart; import org.hibernate.metamodel.mapping.EntityAssociationMapping; import org.hibernate.metamodel.mapping.EntityMappingType; -import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.PluralAttributeMapping; +import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.query.NavigablePath; -import org.hibernate.sql.ast.SqlAstJoinType; -import org.hibernate.sql.ast.spi.SqlAliasBase; -import org.hibernate.sql.ast.spi.SqlAliasBaseManager; -import org.hibernate.sql.ast.spi.SqlAstCreationContext; -import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.sql.ast.tree.from.TableGroupBuilder; -import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.FetchParent; @@ -42,7 +36,6 @@ public class EntityCollectionPart implements CollectionPart, EntityAssociationMa private final Nature nature; private final EntityMappingType entityMappingType; - private ForeignKeyDescriptor foreignKeyDescriptor; private ModelPart fkTargetModelPart; @SuppressWarnings("WeakerAccess") @@ -50,24 +43,20 @@ public class EntityCollectionPart implements CollectionPart, EntityAssociationMa Nature nature, Value bootModelValue, EntityMappingType entityMappingType, - String fkTargetModelPartName, MappingModelCreationProcess creationProcess) { this.nature = nature; this.entityMappingType = entityMappingType; - - creationProcess.registerInitializationCallback( - () -> { - fkTargetModelPart = fkTargetModelPartName == null - ? entityMappingType.getIdentifierMapping() - : entityMappingType.findSubPart( fkTargetModelPartName, entityMappingType ); - assert fkTargetModelPart != null; - - - return true; - } - ); } + public void finishInitialization( + CollectionPersister collectionDescriptor, + Collection bootValueMapping, + String fkTargetModelPartName, + MappingModelCreationProcess creationProcess) { + fkTargetModelPart = entityMappingType.findSubPart( fkTargetModelPartName, null ); + } + + @Override public Nature getNature() { return nature; @@ -78,24 +67,6 @@ public class EntityCollectionPart implements CollectionPart, EntityAssociationMa return getEntityMappingType(); } - @Override - public void applyPrimaryTableReference( - TableGroupBuilder tableGroupBuilder, - SqlExpressionResolver sqlExpressionResolver, - SqlAstCreationContext creationContext) { - tableGroupBuilder.applySecondaryTableReferences( - getEntityMappingType().createPrimaryTableReference( tableGroupBuilder.getSqlAliasBase(), sqlExpressionResolver, creationContext ), - SqlAstJoinType.LEFT, - (lhs, rhs, sqlAstJoinType) -> foreignKeyDescriptor.generateJoinPredicate( - lhs, - rhs, - sqlAstJoinType, - sqlExpressionResolver, - creationContext - ) - ); - } - @Override public EntityMappingType getEntityMappingType() { return entityMappingType; 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 86b7b3e509..d126d5db8d 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 @@ -719,6 +719,7 @@ public class MappingModelCreationHelper { dialect, creationProcess ); + final CollectionPart indexDescriptor; CollectionIdentifierDescriptor identifierDescriptor = null; @@ -882,7 +883,7 @@ public class MappingModelCreationHelper { sessionFactory ); - return new PluralAttributeMappingImpl( + final PluralAttributeMappingImpl pluralAttributeMapping = new PluralAttributeMappingImpl( attrName, bootValueMapping, propertyAccess, @@ -905,6 +906,22 @@ public class MappingModelCreationHelper { declaringType, collectionDescriptor ); + creationProcess.registerInitializationCallback( + () -> { + try { + pluralAttributeMapping.finishInitialization( bootProperty, bootValueMapping, creationProcess ); + return true; + } + catch (NotYetImplementedFor6Exception nye) { + throw nye; + } + catch (Exception wait) { + return false; + } + } + ); + + return pluralAttributeMapping; } private static ForeignKeyDescriptor interpretKeyDescriptor( @@ -1095,29 +1112,38 @@ public class MappingModelCreationHelper { } if ( bootMapKeyDescriptor instanceof OneToMany || bootMapKeyDescriptor instanceof ToOne ) { - final EntityPersister associatedEntity; - - if ( bootMapKeyDescriptor instanceof OneToMany ) { - associatedEntity = creationProcess.getEntityPersister( - ( (OneToMany) bootMapKeyDescriptor ).getReferencedEntityName() - ); - } - else { - // many-to-many - associatedEntity = creationProcess.getEntityPersister( - ( (ToOne) bootMapKeyDescriptor ).getReferencedEntityName() - ); - } - final EntityType indexEntityType = (EntityType) collectionDescriptor.getIndexType(); + final EntityPersister associatedEntity = creationProcess.getEntityPersister( indexEntityType.getAssociatedEntityName() ); - return new EntityCollectionPart( - CollectionPart.Nature.ELEMENT, - bootValueMapping.getElement(), + final EntityCollectionPart indexDescriptor = new EntityCollectionPart( + CollectionPart.Nature.INDEX, + bootMapKeyDescriptor, associatedEntity, - indexEntityType.getRHSUniqueKeyPropertyName(), creationProcess ); + + creationProcess.registerInitializationCallback( + () -> { + try { + indexDescriptor.finishInitialization( + collectionDescriptor, + bootValueMapping, + indexEntityType.getRHSUniqueKeyPropertyName(), + creationProcess + ); + + return true; + } + catch (NotYetImplementedFor6Exception nye) { + throw nye; + } + catch (Exception wait) { + return false; + } + } + ); + + return indexDescriptor; } throw new NotYetImplementedFor6Exception( @@ -1176,29 +1202,38 @@ public class MappingModelCreationHelper { } if ( element instanceof OneToMany || element instanceof ToOne ) { - final EntityPersister associatedEntity; + final EntityType elementEntityType = (EntityType) collectionDescriptor.getElementType(); + final EntityPersister associatedEntity = creationProcess.getEntityPersister( elementEntityType.getAssociatedEntityName() ); - if ( element instanceof OneToMany ) { - associatedEntity = creationProcess.getEntityPersister( - ( (OneToMany) element ).getReferencedEntityName() - ); - } - else { - // many-to-many - associatedEntity = creationProcess.getEntityPersister( - ( (ToOne) element ).getReferencedEntityName() - ); - } - - final EntityType indexEntityType = (EntityType) collectionDescriptor.getElementType(); - - return new EntityCollectionPart( + final EntityCollectionPart elementDescriptor = new EntityCollectionPart( CollectionPart.Nature.ELEMENT, bootDescriptor.getElement(), associatedEntity, - indexEntityType.getRHSUniqueKeyPropertyName(), creationProcess ); + + creationProcess.registerInitializationCallback( + () -> { + try { + elementDescriptor.finishInitialization( + collectionDescriptor, + bootDescriptor, + elementEntityType.getRHSUniqueKeyPropertyName(), + creationProcess + ); + + return true; + } + catch (NotYetImplementedFor6Exception nye) { + throw nye; + } + catch (Exception wait) { + return false; + } + } + ); + + return elementDescriptor; } throw new NotYetImplementedFor6Exception( diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationProcess.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationProcess.java index 33a3a4e0a6..3aacbaf3a2 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationProcess.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationProcess.java @@ -82,6 +82,11 @@ public class MappingModelCreationProcess { postInitCallbacks.remove( callback ); } } + + if ( copy.size() == postInitCallbacks.size() ) { + // none of the processes could complete fully, this is an error + throw new IllegalStateException( "No post-init callbacks could complete" ); + } } } 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 aaf49ba1c7..9184292716 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 @@ -6,16 +6,22 @@ */ package org.hibernate.metamodel.mapping.internal; +import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Supplier; import org.hibernate.LockMode; +import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.engine.FetchStrategy; import org.hibernate.engine.FetchTiming; import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.mapping.Collection; +import org.hibernate.mapping.IndexedCollection; import org.hibernate.mapping.List; +import org.hibernate.mapping.Property; +import org.hibernate.mapping.Value; +import org.hibernate.metamodel.mapping.BasicValuedModelPart; import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor; import org.hibernate.metamodel.mapping.CollectionMappingType; import org.hibernate.metamodel.mapping.CollectionPart; @@ -26,6 +32,7 @@ import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess; import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.Joinable; import org.hibernate.property.access.spi.PropertyAccess; import org.hibernate.query.NavigablePath; @@ -36,8 +43,8 @@ import org.hibernate.sql.ast.spi.SqlAliasStemHelper; import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlAstCreationState; import org.hibernate.sql.ast.spi.SqlExpressionResolver; +import org.hibernate.sql.ast.tree.from.StandardTableGroup; import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.sql.ast.tree.from.TableGroupBuilder; import org.hibernate.sql.ast.tree.from.TableGroupJoin; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.TableReferenceCollector; @@ -50,11 +57,14 @@ import org.hibernate.sql.results.graph.FetchParent; import org.hibernate.sql.results.graph.collection.internal.CollectionDomainResult; import org.hibernate.sql.results.graph.collection.internal.DelayedCollectionFetch; import org.hibernate.sql.results.graph.collection.internal.EagerCollectionFetch; +import org.hibernate.type.EntityType; +import org.hibernate.type.ForeignKeyDirection; /** * @author Steve Ebersole */ public class PluralAttributeMappingImpl extends AbstractAttributeMapping implements PluralAttributeMapping { + public interface Aware { void injectAttributeMapping(PluralAttributeMapping attributeMapping); } @@ -78,6 +88,8 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme private final IndexMetadata indexMetadata; + private ForeignKeyDescriptor manyToManyFkDescriptor; + @SuppressWarnings("WeakerAccess") public PluralAttributeMappingImpl( String attributeName, @@ -152,6 +164,56 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme } } + public void finishInitialization( + Property bootProperty, + Collection bootDescriptor, + MappingModelCreationProcess creationProcess) { + if ( collectionDescriptor.getElementType() instanceof EntityType + || collectionDescriptor.getIndexType() instanceof EntityType ) { + + final EntityPersister associatedEntityDescriptor; + final ModelPart fkTargetPart; + final Value fkBootDescriptorSource; + if ( collectionDescriptor.getElementType() instanceof EntityType ) { + final EntityType elementEntityType = (EntityType) collectionDescriptor.getElementType(); + associatedEntityDescriptor = creationProcess.getEntityPersister( elementEntityType.getAssociatedEntityName() ); + fkTargetPart = elementEntityType.isReferenceToPrimaryKey() + ? associatedEntityDescriptor.getIdentifierMapping() + : associatedEntityDescriptor.findSubPart( elementEntityType.getRHSUniqueKeyPropertyName() ); + fkBootDescriptorSource = bootDescriptor.getElement(); + } + else { + assert collectionDescriptor.getIndexType() != null; + assert bootDescriptor instanceof IndexedCollection; + + final EntityType indexEntityType = (EntityType) collectionDescriptor.getIndexType(); + associatedEntityDescriptor = creationProcess.getEntityPersister( indexEntityType.getAssociatedEntityName() ); + fkTargetPart = indexEntityType.isReferenceToPrimaryKey() + ? associatedEntityDescriptor.getIdentifierMapping() + : associatedEntityDescriptor.findSubPart( indexEntityType.getRHSUniqueKeyPropertyName() ); + fkBootDescriptorSource = ( (IndexedCollection) bootDescriptor ).getIndex(); + } + + if ( fkTargetPart instanceof BasicValuedModelPart ) { + final BasicValuedModelPart basicFkTargetPart = (BasicValuedModelPart) fkTargetPart; + final Joinable collectionDescriptorAsJoinable = (Joinable) collectionDescriptor; + manyToManyFkDescriptor = new SimpleForeignKeyDescriptor( + ForeignKeyDirection.TO_PARENT, + collectionDescriptorAsJoinable.getTableName(), + fkBootDescriptorSource.getColumnIterator().next().getText(), + basicFkTargetPart.getContainingTableExpression(), + basicFkTargetPart.getMappedColumnExpression(), + basicFkTargetPart.getJdbcMapping() + ); + } + else { + throw new NotYetImplementedFor6Exception( + "Support for composite foreign keys not yet implemented : " + collectionDescriptor.getRole() + ); + } + } + } + @Override public CollectionMappingType getMappedTypeDescriptor() { return (CollectionMappingType) super.getMappedTypeDescriptor(); @@ -301,41 +363,51 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme SqlAliasBaseGenerator aliasBaseGenerator, SqlExpressionResolver sqlExpressionResolver, SqlAstCreationContext creationContext) { - final String aliasRoot = explicitSourceAlias == null ? sqlAliasStem : explicitSourceAlias; - final SqlAliasBase sqlAliasBase = aliasBaseGenerator.createSqlAliasBase( aliasRoot ); - - final TableGroupBuilder tableGroupBuilder = TableGroupBuilder.builder( + final CollectionPersister collectionDescriptor = getCollectionDescriptor(); + if ( collectionDescriptor.isOneToMany() ) { + return createOneToManyTableGroupJoin( + navigablePath, + lhs, + explicitSourceAlias, + sqlAstJoinType, + lockMode, + aliasBaseGenerator, + sqlExpressionResolver, + creationContext + ); + } + else { + return createCollectionTableGroupJoin( + navigablePath, + lhs, + explicitSourceAlias, + sqlAstJoinType, + lockMode, + aliasBaseGenerator, + sqlExpressionResolver, + creationContext + ); + } + } + private TableGroupJoin createOneToManyTableGroupJoin( + NavigablePath navigablePath, + TableGroup lhs, + String explicitSourceAlias, + SqlAstJoinType sqlAstJoinType, + LockMode lockMode, + SqlAliasBaseGenerator aliasBaseGenerator, + SqlExpressionResolver sqlExpressionResolver, + SqlAstCreationContext creationContext) { + final TableGroup tableGroup = createOneToManyTableGroup( navigablePath, - this, + sqlAstJoinType == SqlAstJoinType.INNER + && ! getAttributeMetadataAccess().resolveAttributeMetadata( null ).isNullable(), lockMode, - sqlAliasBase, - (tableExpression, tableGroup) -> createTableReferenceJoin( - tableExpression, - sqlAliasBase, - tableGroup.getPrimaryTableReference(), - sqlAstJoinType == SqlAstJoinType.INNER && ! getAttributeMetadataAccess().resolveAttributeMetadata( null ).isNullable(), - sqlExpressionResolver, - creationContext - ), - creationContext.getSessionFactory() - ); - - tableGroupBuilder.applyPrimaryReference( - // returns null when there is no "collection table" - getCollectionDescriptor().createPrimaryTableReference( - sqlAliasBase, - sqlExpressionResolver, - creationContext - ) - ); - - elementDescriptor.applyPrimaryTableReference( - tableGroupBuilder, + aliasBaseGenerator, sqlExpressionResolver, creationContext ); - final TableGroup tableGroup = tableGroupBuilder.build(); final TableGroupJoin tableGroupJoin = new TableGroupJoin( navigablePath, sqlAstJoinType, @@ -354,19 +426,188 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme return tableGroupJoin; } + private TableGroup createOneToManyTableGroup( + NavigablePath navigablePath, + boolean canUseInnerJoins, + LockMode lockMode, + SqlAliasBaseGenerator aliasBaseGenerator, + SqlExpressionResolver sqlExpressionResolver, + SqlAstCreationContext creationContext) { + final EntityCollectionPart entityPartDescriptor; + if ( elementDescriptor instanceof EntityCollectionPart ) { + entityPartDescriptor = (EntityCollectionPart) elementDescriptor; + } + else { + assert indexDescriptor instanceof EntityCollectionPart; + entityPartDescriptor = (EntityCollectionPart) indexDescriptor; + } + + final SqlAliasBase sqlAliasBase = aliasBaseGenerator.createSqlAliasBase( getSqlAliasStem() ); + + final TableReference primaryTableReference = entityPartDescriptor.getEntityMappingType().createPrimaryTableReference( + sqlAliasBase, + sqlExpressionResolver, + creationContext + ); + + return new StandardTableGroup( + navigablePath, + this, + lockMode, + primaryTableReference, + sqlAliasBase, + (tableExpression, tg) -> createTableReferenceJoin( + tableExpression, + sqlAliasBase, + primaryTableReference, + canUseInnerJoins, + sqlExpressionResolver, + creationContext + ), + creationContext.getSessionFactory() + ); + } + + private TableGroupJoin createCollectionTableGroupJoin( + NavigablePath navigablePath, + TableGroup lhs, + String explicitSourceAlias, + SqlAstJoinType sqlAstJoinType, + LockMode lockMode, + SqlAliasBaseGenerator aliasBaseGenerator, + SqlExpressionResolver sqlExpressionResolver, + SqlAstCreationContext creationContext) { + final TableGroup tableGroup = createCollectionTableGroup( + navigablePath, + sqlAstJoinType == SqlAstJoinType.INNER + && !getAttributeMetadataAccess().resolveAttributeMetadata( null ).isNullable(), + lockMode, + aliasBaseGenerator, + sqlExpressionResolver, + creationContext + ); + + final TableGroupJoin tableGroupJoin = new TableGroupJoin( + navigablePath, + sqlAstJoinType, + tableGroup, + getKeyDescriptor().generateJoinPredicate( + lhs, + tableGroup, + sqlAstJoinType, + sqlExpressionResolver, + creationContext + ) + ); + + lhs.addTableGroupJoin( tableGroupJoin ); + + return tableGroupJoin; + } + + private TableGroup createCollectionTableGroup( + NavigablePath navigablePath, + boolean canUseInnerJoin, + LockMode lockMode, + SqlAliasBaseGenerator aliasBaseGenerator, + SqlExpressionResolver sqlExpressionResolver, + SqlAstCreationContext creationContext) { + final SqlAliasBase sqlAliasBase = aliasBaseGenerator.createSqlAliasBase( getSqlAliasStem() ); + + assert ! getCollectionDescriptor().isOneToMany(); + + final String collectionTableName = ( (Joinable) collectionDescriptor ).getTableName(); + final TableReference collectionTableReference = new TableReference( + collectionTableName, + sqlAliasBase.generateNewAlias(), + true, + creationContext.getSessionFactory() + ); + + final Consumer tableGroupFinalizer; + final BiFunction tableReferenceJoinCreator; + if ( elementDescriptor instanceof EntityCollectionPart || indexDescriptor instanceof EntityCollectionPart ) { + final EntityCollectionPart entityPartDescriptor; + if ( elementDescriptor instanceof EntityCollectionPart ) { + entityPartDescriptor = (EntityCollectionPart) elementDescriptor; + } + else { + entityPartDescriptor = (EntityCollectionPart) indexDescriptor; + } + + final EntityMappingType mappingType = entityPartDescriptor.getEntityMappingType(); + final TableReference associatedPrimaryTable = mappingType.createPrimaryTableReference( + sqlAliasBase, + sqlExpressionResolver, + creationContext + ); + + tableReferenceJoinCreator = (tableExpression, tableGroup) -> createTableReferenceJoin( + tableExpression, + sqlAliasBase, + associatedPrimaryTable, + canUseInnerJoin && ! getAttributeMetadataAccess().resolveAttributeMetadata( null ).isNullable(), + sqlExpressionResolver, + creationContext + ); + + tableGroupFinalizer = tableGroup -> { + final SqlAstJoinType joinType = canUseInnerJoin && ! getAttributeMetadataAccess().resolveAttributeMetadata( null ).isNullable() + ? SqlAstJoinType.INNER + : SqlAstJoinType.LEFT; + final TableReferenceJoin associationJoin = new TableReferenceJoin( + joinType, + associatedPrimaryTable, + manyToManyFkDescriptor.generateJoinPredicate( + collectionTableReference, + associatedPrimaryTable, + joinType, + sqlExpressionResolver, + creationContext + ) + ); + ( (StandardTableGroup) tableGroup ).addTableReferenceJoin( associationJoin ); + }; + } + else { + tableReferenceJoinCreator = (tableExpression, tableGroup) -> { + throw new UnsupportedOperationException( + "element-collection cannot contain joins : " + collectionTableReference.getTableExpression() + " -> " + tableExpression + ); + }; + tableGroupFinalizer = null; + } + + final StandardTableGroup tableGroup = new StandardTableGroup( + navigablePath, + this, + lockMode, + collectionTableReference, + sqlAliasBase, + tableReferenceJoinCreator, + creationContext.getSessionFactory() + ); + + if ( tableGroupFinalizer != null ) { + tableGroupFinalizer.accept( tableGroup ); + } + + return tableGroup; + } + @Override public TableReferenceJoin createTableReferenceJoin( String joinTableExpression, SqlAliasBase sqlAliasBase, TableReference lhs, - boolean sqlAstJoinType, + boolean canUseInnerJoin, SqlExpressionResolver sqlExpressionResolver, SqlAstCreationContext creationContext) { return getCollectionDescriptor().createTableReferenceJoin( joinTableExpression, sqlAliasBase, lhs, - sqlAstJoinType, + canUseInnerJoin, sqlExpressionResolver, creationContext ); @@ -410,62 +651,26 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme SqlExpressionResolver sqlExpressionResolver, Supplier> additionalPredicateCollectorAccess, SqlAstCreationContext creationContext) { - final SqlAliasBase sqlAliasBase = aliasBaseGenerator.createSqlAliasBase( getSqlAliasStem() ); - - final TableGroupBuilder tableGroupBuilder = TableGroupBuilder.builder( - navigablePath, - this, - lockMode, - sqlAliasBase, - (tableExpression, tableGroup) -> createTableReferenceJoin( - tableExpression, - sqlAliasBase, - tableGroup.getPrimaryTableReference(), - canUseInnerJoins && ! getAttributeMetadataAccess().resolveAttributeMetadata( null ).isNullable(), - sqlExpressionResolver, - creationContext - ), - creationContext.getSessionFactory() - ); - - getElementDescriptor().applyPrimaryTableReference( - tableGroupBuilder, - sqlExpressionResolver, - creationContext - ); - - if ( getIndexDescriptor() != null ) { - getIndexDescriptor().applyPrimaryTableReference( - tableGroupBuilder, + if ( getCollectionDescriptor().isOneToMany() ) { + return createOneToManyTableGroup( + navigablePath, + canUseInnerJoins, + lockMode, + aliasBaseGenerator, sqlExpressionResolver, creationContext ); } - - final TableReference collectionTableReference = getCollectionDescriptor().createPrimaryTableReference( - sqlAliasBase, - sqlExpressionResolver, - creationContext - ); - - if ( collectionTableReference != null ) { - tableGroupBuilder.applySecondaryTableReferences( - collectionTableReference, - canUseInnerJoins && ! getAttributeMetadataAccess().resolveAttributeMetadata( null ).isNullable() - ? SqlAstJoinType.INNER - : SqlAstJoinType.LEFT, - (lhs, rhs, sqlAstJoinType) -> fkDescriptor.generateJoinPredicate( - lhs, - rhs, - sqlAstJoinType, - sqlExpressionResolver, - creationContext - ) - + else { + return createCollectionTableGroup( + navigablePath, + canUseInnerJoins, + lockMode, + aliasBaseGenerator, + sqlExpressionResolver, + creationContext ); } - - return tableGroupBuilder.build(); } @Override 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 161e33ba11..fef394fcae 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 @@ -28,8 +28,8 @@ import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlAstCreationState; import org.hibernate.sql.ast.spi.SqlAstProcessingState; import org.hibernate.sql.ast.spi.SqlExpressionResolver; +import org.hibernate.sql.ast.tree.from.StandardTableGroup; import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.sql.ast.tree.from.TableGroupBuilder; import org.hibernate.sql.ast.tree.from.TableGroupJoin; import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer; import org.hibernate.sql.ast.tree.from.TableReference; @@ -207,15 +207,22 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu final String aliasRoot = explicitSourceAlias == null ? sqlAliasStem : explicitSourceAlias; final SqlAliasBase sqlAliasBase = aliasBaseGenerator.createSqlAliasBase( aliasRoot ); - final TableGroupBuilder tableGroupBuilder = TableGroupBuilder.builder( + final TableReference primaryTableReference = createPrimaryTableReference( + sqlAliasBase, + sqlExpressionResolver, + creationContext + ); + + final TableGroup tableGroup = new StandardTableGroup( navigablePath, this, lockMode, + primaryTableReference, sqlAliasBase, - (tableExpression, tableGroup) -> createTableReferenceJoin( + (tableExpression, tg) -> createTableReferenceJoin( tableExpression, sqlAliasBase, - tableGroup.getPrimaryTableReference(), + primaryTableReference, false, sqlExpressionResolver, creationContext @@ -223,25 +230,6 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu creationContext.getSessionFactory() ); - tableGroupBuilder.applyPrimaryReference( - getEntityMappingType().createPrimaryTableReference( - sqlAliasBase, - sqlExpressionResolver, - creationContext - ) - ); - -// applyTableReferences( -// sqlAliasBase, -// joinType, -// tableGroupBuilder, -// sqlExpressionResolver, -// creationContext -// ); - - getMappedTypeDescriptor().getIdentifierMapping(); - - final TableGroup tableGroup = tableGroupBuilder.build(); final TableGroupJoin tableGroupJoin = new TableGroupJoin( navigablePath, sqlAstJoinType, diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java index 9bfae0e4c2..4c94c977b5 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java @@ -1882,6 +1882,10 @@ public abstract class AbstractCollectionPersister return elementPersister; } + protected EntityPersister getElementPersisterInternal() { + return elementPersister; + } + @Override public boolean isCollection() { return true; @@ -2468,65 +2472,6 @@ public abstract class AbstractCollectionPersister return false; } - @Override - public TableReference createPrimaryTableReference( - SqlAliasBase sqlAliasBase, - SqlExpressionResolver sqlExpressionResolver, - SqlAstCreationContext creationContext) { - if ( qualifiedTableName != null && ! isOneToMany() ) { - return new TableReference( - qualifiedTableName, - sqlAliasBase.generateNewAlias(), - false, - getFactory() - ); - } - - return null; - } - - @Override - public TableReferenceJoin createTableReferenceJoin( - String joinTableExpression, - SqlAliasBase sqlAliasBase, - TableReference lhs, - boolean canUseInnerJoin, - SqlExpressionResolver sqlExpressionResolver, - SqlAstCreationContext creationContext) { - if ( elementPersister == null ) { - return null; - } - - final String entityPrimaryTableName = ( (Joinable) elementPersister ).getTableName(); - if ( entityPrimaryTableName.equals( joinTableExpression ) ) { - assert qualifiedTableName != null; - assert lhs.getTableExpression().equals( qualifiedTableName ); - - final TableReference tableReference = elementPersister.createPrimaryTableReference( sqlAliasBase, sqlExpressionResolver, creationContext ); - final SqlAstJoinType sqlAstJoinType = canUseInnerJoin ? SqlAstJoinType.INNER : SqlAstJoinType.LEFT; - return new TableReferenceJoin( - sqlAstJoinType, - tableReference, - generateEntityElementJoinPredicate( - lhs, - tableReference, - sqlAstJoinType, - sqlExpressionResolver, - creationContext - ) - ); - } - - return elementPersister.createTableReferenceJoin( - joinTableExpression, - sqlAliasBase, - lhs, - canUseInnerJoin, - sqlExpressionResolver, - creationContext - ); - } - @Override public void applyTableReferences( SqlAliasBase sqlAliasBase, @@ -2713,10 +2658,6 @@ public abstract class AbstractCollectionPersister SqlAstCreationContext creationContext) { final SessionFactoryImplementor sessionFactory = creationContext.getSessionFactory(); - // `lhs` should be the collection table - // `rhs` should be the primary element table - assert lhs.getTableExpression().equals( getTableName() ); - final String fkTargetModelPartName = getCollectionType().getRHSUniqueKeyPropertyName(); final ModelPart fkTargetDescriptor; if ( fkTargetModelPartName != null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java index af45b1cdc3..f1b8acde24 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java @@ -15,6 +15,7 @@ import java.util.Set; import org.hibernate.HibernateException; import org.hibernate.MappingException; +import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.cache.CacheException; import org.hibernate.cache.spi.access.CollectionDataAccess; import org.hibernate.collection.spi.PersistentCollection; @@ -26,6 +27,7 @@ import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.jdbc.Expectation; import org.hibernate.jdbc.Expectations; import org.hibernate.mapping.Collection; +import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.Joinable; import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.pretty.MessageHelper; @@ -33,6 +35,12 @@ import org.hibernate.sql.Delete; import org.hibernate.sql.Insert; import org.hibernate.sql.SelectFragment; import org.hibernate.sql.Update; +import org.hibernate.sql.ast.SqlAstJoinType; +import org.hibernate.sql.ast.spi.SqlAliasBase; +import org.hibernate.sql.ast.spi.SqlAstCreationContext; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; +import org.hibernate.sql.ast.tree.from.TableReference; +import org.hibernate.sql.ast.tree.from.TableReferenceJoin; import org.hibernate.type.AssociationType; /** diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java index 7622b80a00..b1a18a6216 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java @@ -24,11 +24,17 @@ import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.jdbc.Expectation; import org.hibernate.jdbc.Expectations; import org.hibernate.mapping.Collection; +import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.Joinable; import org.hibernate.persister.entity.OuterJoinLoadable; import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.pretty.MessageHelper; import org.hibernate.sql.Update; +import org.hibernate.sql.ast.spi.SqlAliasBase; +import org.hibernate.sql.ast.spi.SqlAstCreationContext; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; +import org.hibernate.sql.ast.tree.from.TableReference; +import org.hibernate.sql.ast.tree.from.TableReferenceJoin; /** * Collection persister for one-to-many associations. @@ -67,6 +73,43 @@ public class OneToManyPersister extends AbstractCollectionPersister { keyIsUpdateable = collectionBinding.getKey().isUpdateable(); } + @Override + public TableReference createPrimaryTableReference( + SqlAliasBase sqlAliasBase, + SqlExpressionResolver sqlExpressionResolver, + SqlAstCreationContext creationContext) { + // for a one-to-many, the "primary table" is the primary table of the associated entity + final EntityPersister elementPersister = getElementPersister(); + assert elementPersister != null; + + return elementPersister.createPrimaryTableReference( sqlAliasBase, sqlExpressionResolver, creationContext ); + } + + @Override + public TableReferenceJoin createTableReferenceJoin( + String joinTableExpression, + SqlAliasBase sqlAliasBase, + TableReference lhs, + boolean canUseInnerJoin, + SqlExpressionResolver sqlExpressionResolver, + SqlAstCreationContext creationContext) { + final EntityPersister elementPersister = getElementPersister(); + assert elementPersister != null; + + assert qualifiedTableName != null; + assert lhs.getTableExpression().equals( qualifiedTableName ); + assert lhs.getTableExpression().equals( ( (Joinable) elementPersister ).getTableName() ); + + return elementPersister.createTableReferenceJoin( + joinTableExpression, + sqlAliasBase, + lhs, + canUseInnerJoin, + sqlExpressionResolver, + creationContext + ); + } + /** * Generate the SQL UPDATE that updates all the foreign keys to null */ diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index e7c260743b..8b26dc594d 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -181,8 +181,8 @@ import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.expression.Expression; +import org.hibernate.sql.ast.tree.from.StandardTableGroup; import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.sql.ast.tree.from.TableGroupBuilder; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.TableReferenceCollector; import org.hibernate.sql.ast.tree.from.TableReferenceJoin; @@ -1225,10 +1225,17 @@ public abstract class AbstractEntityPersister SqlAstCreationContext creationContext) { final SqlAliasBase sqlAliasBase = aliasBaseGenerator.createSqlAliasBase( getSqlAliasStem() ); - final TableGroupBuilder builder = TableGroupBuilder.builder( + final TableReference primaryTableReference = createPrimaryTableReference( + sqlAliasBase, + sqlExpressionResolver, + creationContext + ); + + return new StandardTableGroup( navigablePath, this, lockMode, + primaryTableReference, sqlAliasBase, (tableExpression, tableGroup) -> { for ( int i = 0; i < getSubclassTableSpan(); i++ ) { @@ -1251,7 +1258,7 @@ public abstract class AbstractEntityPersister ), joinedTableReference, generateJoinPredicate( - tableGroup.getPrimaryTableReference(), + primaryTableReference, joinedTableReference, i, sqlExpressionResolver @@ -1262,27 +1269,8 @@ public abstract class AbstractEntityPersister return null; }, - creationContext.getSessionFactory() + getFactory() ); - - - builder.applyPrimaryReference( - createPrimaryTableReference( - sqlAliasBase, - sqlExpressionResolver, - creationContext - ) - ); - - // applyTableReferences( -// sqlAliasBase, -// tableReferenceJoinType, -// builder, -// sqlExpressionResolver, -// creationContext -// ); - - return builder.build(); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/ExecuteWithIdTableHelper.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/ExecuteWithIdTableHelper.java index 2a41c2faa0..f9c2056d27 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/ExecuteWithIdTableHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/ExecuteWithIdTableHelper.java @@ -166,7 +166,6 @@ public final class ExecuteWithIdTableHelper { idTableReference, Collections.emptyList(), null, - null, executionContext.getSession().getFactory() ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/ExecuteWithoutIdTableHelper.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/ExecuteWithoutIdTableHelper.java index aba9c6b5ae..55445c2e06 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/ExecuteWithoutIdTableHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/ExecuteWithoutIdTableHelper.java @@ -47,7 +47,6 @@ public final class ExecuteWithoutIdTableHelper { rootTableReference, Collections.emptyList(), null, - null, sessionFactory ); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/cte/CteTable.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/cte/CteTable.java index fe3745ba2b..5f3d445e40 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/cte/CteTable.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/cte/CteTable.java @@ -89,7 +89,6 @@ public class CteTable { tableValueConstructorReference, Collections.emptyList(), null, - null, sessionFactory ); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/StandardTableGroup.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/StandardTableGroup.java index dd1872212b..90f6433f20 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/StandardTableGroup.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/StandardTableGroup.java @@ -33,11 +33,24 @@ public class StandardTableGroup extends AbstractTableGroup { TableReference primaryTableReference, List tableJoins, SqlAliasBase sqlAliasBase, - BiFunction tableReferenceJoinCreator, SessionFactoryImplementor sessionFactory) { super( navigablePath, tableGroupProducer, lockMode, sqlAliasBase, sessionFactory ); this.primaryTableReference = primaryTableReference; this.tableJoins = tableJoins; + this.tableReferenceJoinCreator = null; + } + + public StandardTableGroup( + NavigablePath navigablePath, + TableGroupProducer tableGroupProducer, + LockMode lockMode, + TableReference primaryTableReference, + SqlAliasBase sqlAliasBase, + BiFunction tableReferenceJoinCreator, + SessionFactoryImplementor sessionFactory) { + super( navigablePath, tableGroupProducer, lockMode, sqlAliasBase, sessionFactory ); + this.primaryTableReference = primaryTableReference; + this.tableJoins = null; this.tableReferenceJoinCreator = tableReferenceJoinCreator; } @@ -60,6 +73,14 @@ public class StandardTableGroup extends AbstractTableGroup { return tableJoins == null ? Collections.emptyList() : tableJoins; } + public void addTableReferenceJoin(TableReferenceJoin join) { + if ( tableJoins == null ) { + tableJoins = new ArrayList<>(); + } + + tableJoins.add( join ); + } + @Override public TableReference resolveTableReferenceInternal(String tableExpression) { final TableReference tableReference = super.resolveTableReferenceInternal( tableExpression ); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupBuilder.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupBuilder.java deleted file mode 100644 index 1e82c2bcfa..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupBuilder.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * 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 http://www.gnu.org/licenses/lgpl-2.1.html - */ -package org.hibernate.sql.ast.tree.from; - -import java.util.ArrayList; -import java.util.function.BiFunction; - -import org.hibernate.LockMode; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.query.NavigablePath; -import org.hibernate.sql.ast.SqlAstJoinType; -import org.hibernate.sql.ast.spi.SqlAliasBase; - -/** - * @author Steve Ebersole - */ -public class TableGroupBuilder implements TableReferenceCollector { - public static TableGroupBuilder builder( - NavigablePath path, - TableGroupProducer producer, - LockMode lockMode, - SqlAliasBase sqlAliasBase, - BiFunction tableReferenceJoinCreator, - SessionFactoryImplementor sessionFactory) { - return new TableGroupBuilder( path, producer, lockMode, sqlAliasBase, tableReferenceJoinCreator, sessionFactory ); - } - - private final NavigablePath path; - private final TableGroupProducer producer; - private final BiFunction tableReferenceJoinCreator; - private final SessionFactoryImplementor sessionFactory; - - private final SqlAliasBase sqlAliasBase; - private final LockMode lockMode; - - private BiFunction primaryJoinProducer; - - private TableReference primaryTableReference; - private TableReference secondaryTableLhs; - - private java.util.List tableJoins; - - private TableGroupBuilder( - NavigablePath path, - TableGroupProducer producer, - LockMode lockMode, - SqlAliasBase sqlAliasBase, - BiFunction tableReferenceJoinCreator, - SessionFactoryImplementor sessionFactory) { - this.path = path; - this.producer = producer; - this.lockMode = lockMode; - this.sqlAliasBase = sqlAliasBase; - this.tableReferenceJoinCreator = tableReferenceJoinCreator; - this.sessionFactory = sessionFactory; - } - - public NavigablePath getPath() { - return path; - } - - public SessionFactoryImplementor getSessionFactory() { - return sessionFactory; - } - - public SqlAliasBase getSqlAliasBase() { - return sqlAliasBase; - } - - @Override - public void applyPrimaryJoinProducer(BiFunction primaryJoinProducer) { - this.primaryJoinProducer = primaryJoinProducer; - } - - public TableGroup build() { - if ( primaryTableReference == null ) { - throw new IllegalStateException( "Primary TableReference was not specified : " + path ); - } - - return new StandardTableGroup( - path, - producer, - lockMode, - primaryTableReference, - tableJoins, - sqlAliasBase, - tableReferenceJoinCreator, - sessionFactory - ); - } - - @Override - public void applyPrimaryReference(TableReference tableReference) { - if ( primaryTableReference != null ) { - assert primaryJoinProducer != null; - addTableReferenceJoin( primaryJoinProducer.apply( primaryTableReference, tableReference ) ); - } - else { - primaryTableReference = tableReference; - } - - secondaryTableLhs = tableReference; - } - - @Override - public void applySecondaryTableReferences( - TableReference tableReference, - SqlAstJoinType tableReferenceSqlAstJoinType, - TableReferenceJoinPredicateProducer predicateProducer) { - if ( primaryTableReference == null ) { - primaryTableReference = tableReference; - secondaryTableLhs = primaryTableReference; - } - else { - addTableReferenceJoin( - new TableReferenceJoin( - tableReferenceSqlAstJoinType, - tableReference, - predicateProducer.producePredicate( - secondaryTableLhs, - tableReference, - tableReferenceSqlAstJoinType - ) - ) - ); - } - } - - public void addTableReferenceJoin(TableReferenceJoin join) { - if ( tableJoins == null ) { - tableJoins = new ArrayList<>(); - } - tableJoins.add( join ); - } -}