From 7d0da9e505026c2da29b41fc42fe7af497378979 Mon Sep 17 00:00:00 2001 From: Sanne Grinovero Date: Tue, 4 Jul 2023 21:01:50 +0100 Subject: [PATCH] HHH-16900 Optimise implementations of MutationOperationGroup --- .../EntityMutationOperationGroup.java | 26 +++++ .../internal/MutationExecutorPostInsert.java | 4 +- ...MutationExecutorPostInsertSingleTable.java | 4 +- .../StandardMutationExecutorService.java | 17 +-- .../AbstractEntityCollectionPart.java | 1 + .../collection/OneToManyPersister.java | 4 +- .../DeleteRowsCoordinatorStandard.java | 9 +- ...DeleteRowsCoordinatorTablePerSubclass.java | 13 +-- .../InsertRowsCoordinatorStandard.java | 9 +- ...InsertRowsCoordinatorTablePerSubclass.java | 22 ++-- .../mutation/RemoveCoordinatorStandard.java | 11 +- .../RemoveCoordinatorTablePerSubclass.java | 17 +-- .../UpdateRowsCoordinatorOneToMany.java | 19 ++-- .../UpdateRowsCoordinatorStandard.java | 22 ++-- ...UpdateRowsCoordinatorTablePerSubclass.java | 15 +-- .../mutation/AbstractMutationCoordinator.java | 35 +++--- .../entity/mutation/InsertCoordinator.java | 17 +-- .../mutation/UpdateCoordinatorNoOp.java | 4 +- .../mutation/UpdateCoordinatorStandard.java | 4 +- .../sql/model/MutationOperationGroup.java | 12 +- .../sql/model/ast/MutationGroup.java | 9 +- .../AbstractMutationOperationGroup.java | 34 ------ .../EntityMutationOperationGroupStandard.java | 106 ++++++++++++++++++ .../sql/model/internal/MutationGroupNone.java | 8 +- .../model/internal/MutationGroupSingle.java | 11 +- .../model/internal/MutationGroupStandard.java | 11 +- .../MutationOperationGroupFactory.java | 74 ++++++++++++ .../internal/MutationOperationGroupNone.java | 47 -------- .../MutationOperationGroupSingle.java | 67 ----------- .../MutationOperationGroupStandard.java | 87 ++++++++++---- 30 files changed, 431 insertions(+), 288 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/EntityMutationOperationGroup.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/sql/model/internal/AbstractMutationOperationGroup.java create mode 100644 hibernate-core/src/main/java/org/hibernate/sql/model/internal/EntityMutationOperationGroupStandard.java create mode 100644 hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationOperationGroupFactory.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationOperationGroupNone.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationOperationGroupSingle.java diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/EntityMutationOperationGroup.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/EntityMutationOperationGroup.java new file mode 100644 index 0000000000..f93dc1af04 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/EntityMutationOperationGroup.java @@ -0,0 +1,26 @@ +/* + * 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.engine.jdbc.mutation.internal; + +import org.hibernate.persister.entity.mutation.EntityMutationTarget; +import org.hibernate.sql.model.MutationOperationGroup; + +public interface EntityMutationOperationGroup extends MutationOperationGroup { + + /** + * The model-part being mutated. + * N.B. it returns a widened type compared to the same method in the super interface. + */ + @Override + EntityMutationTarget getMutationTarget(); + + @Override + default EntityMutationOperationGroup asEntityMutationOperationGroup() { + return this; + } + +} diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/MutationExecutorPostInsert.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/MutationExecutorPostInsert.java index c30349d03b..0e84fa24a8 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/MutationExecutorPostInsert.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/MutationExecutorPostInsert.java @@ -61,8 +61,8 @@ public class MutationExecutorPostInsert implements MutationExecutor, JdbcValueBi protected final JdbcValueBindingsImpl valueBindings; - public MutationExecutorPostInsert(MutationOperationGroup mutationOperationGroup, SharedSessionContractImplementor session) { - this.mutationTarget = (EntityMutationTarget) mutationOperationGroup.getMutationTarget(); + public MutationExecutorPostInsert(EntityMutationOperationGroup mutationOperationGroup, SharedSessionContractImplementor session) { + this.mutationTarget = mutationOperationGroup.getMutationTarget(); this.valueBindings = new JdbcValueBindingsImpl( MutationType.INSERT, mutationTarget, diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/MutationExecutorPostInsertSingleTable.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/MutationExecutorPostInsertSingleTable.java index b85a46bc7a..7c35c26c89 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/MutationExecutorPostInsertSingleTable.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/MutationExecutorPostInsertSingleTable.java @@ -52,9 +52,9 @@ public class MutationExecutorPostInsertSingleTable implements MutationExecutor, private final JdbcValueBindingsImpl valueBindings; public MutationExecutorPostInsertSingleTable( - MutationOperationGroup mutationOperationGroup, + EntityMutationOperationGroup mutationOperationGroup, SharedSessionContractImplementor session) { - this.mutationTarget = (EntityMutationTarget) mutationOperationGroup.getMutationTarget(); + this.mutationTarget = mutationOperationGroup.getMutationTarget(); this.session = session; assert mutationOperationGroup.getNumberOfOperations() == 1; diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/StandardMutationExecutorService.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/StandardMutationExecutorService.java index 0a0bba1192..2226e73911 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/StandardMutationExecutorService.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/StandardMutationExecutorService.java @@ -7,7 +7,6 @@ package org.hibernate.engine.jdbc.mutation.internal; import java.util.Map; -import java.util.function.Supplier; import org.hibernate.cfg.Environment; import org.hibernate.engine.jdbc.batch.spi.BatchKey; @@ -16,11 +15,8 @@ import org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.util.config.ConfigurationHelper; -import org.hibernate.metamodel.mapping.EntityMappingType; -import org.hibernate.persister.entity.mutation.EntityMutationTarget; import org.hibernate.sql.model.MutationOperation; import org.hibernate.sql.model.MutationOperationGroup; -import org.hibernate.sql.model.MutationTarget; import org.hibernate.sql.model.MutationType; import org.hibernate.sql.model.PreparableMutationOperation; import org.hibernate.sql.model.SelfExecutingUpdateOperation; @@ -58,18 +54,15 @@ public MutationExecutor createExecutor( final int numberOfOperations = operationGroup.getNumberOfOperations(); final MutationType mutationType = operationGroup.getMutationType(); - final MutationTarget mutationTarget = operationGroup.getMutationTarget(); + final EntityMutationOperationGroup entityMutationOperationGroup = operationGroup.asEntityMutationOperationGroup(); if ( mutationType == MutationType.INSERT - && mutationTarget instanceof EntityMutationTarget - && ( (EntityMutationTarget) mutationTarget ).getIdentityInsertDelegate() != null ) { - assert mutationTarget instanceof EntityMappingType; - + && entityMutationOperationGroup != null + && entityMutationOperationGroup.getMutationTarget().getIdentityInsertDelegate() != null ) { if ( numberOfOperations > 1 ) { - return new MutationExecutorPostInsert( operationGroup, session ); + return new MutationExecutorPostInsert( entityMutationOperationGroup, session ); } - - return new MutationExecutorPostInsertSingleTable( operationGroup, session ); + return new MutationExecutorPostInsertSingleTable( entityMutationOperationGroup, session ); } if ( numberOfOperations == 1 ) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEntityCollectionPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEntityCollectionPart.java index d4e7ba0cea..b5700d1b76 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEntityCollectionPart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEntityCollectionPart.java @@ -26,6 +26,7 @@ import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.model.domain.NavigableRole; import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.collection.mutation.CollectionMutationTarget; import org.hibernate.persister.entity.PropertyMapping; import org.hibernate.spi.NavigablePath; import org.hibernate.sql.ast.spi.FromClauseAccess; 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 e909790090..f14fc637cf 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 @@ -20,6 +20,7 @@ import org.hibernate.engine.jdbc.mutation.JdbcValueBindings; import org.hibernate.engine.jdbc.mutation.MutationExecutor; import org.hibernate.engine.jdbc.mutation.ParameterUsage; +import org.hibernate.sql.model.internal.MutationOperationGroupFactory; import org.hibernate.engine.jdbc.mutation.internal.MutationQueryOptions; import org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService; import org.hibernate.engine.spi.SharedSessionContractImplementor; @@ -74,7 +75,6 @@ import org.hibernate.sql.model.ast.RestrictedTableMutation; import org.hibernate.sql.model.ast.TableUpdate; import org.hibernate.sql.model.ast.builder.TableUpdateBuilderStandard; -import org.hibernate.sql.model.internal.MutationOperationGroupSingle; import org.hibernate.sql.model.internal.TableUpdateStandard; import org.hibernate.sql.model.jdbc.JdbcDeleteMutation; import org.hibernate.sql.model.jdbc.JdbcMutationOperation; @@ -229,7 +229,7 @@ && hasIndex() final MutationExecutor mutationExecutor = mutationExecutorService.createExecutor( () -> new BasicBatchKey( getNavigableRole() + "#INDEX" ), - new MutationOperationGroupSingle( MutationType.UPDATE, this, updateRowOperation ), + MutationOperationGroupFactory.singleOperation( MutationType.UPDATE, this, updateRowOperation ), session ); diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/DeleteRowsCoordinatorStandard.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/DeleteRowsCoordinatorStandard.java index 64ad368596..fa490124b2 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/DeleteRowsCoordinatorStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/DeleteRowsCoordinatorStandard.java @@ -12,13 +12,14 @@ import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey; import org.hibernate.engine.jdbc.mutation.JdbcValueBindings; import org.hibernate.engine.jdbc.mutation.MutationExecutor; +import org.hibernate.sql.model.internal.MutationOperationGroupFactory; import org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.service.ServiceRegistry; +import org.hibernate.sql.model.MutationOperationGroup; import org.hibernate.sql.model.MutationType; -import org.hibernate.sql.model.internal.MutationOperationGroupSingle; import org.hibernate.sql.model.jdbc.JdbcMutationOperation; import static org.hibernate.sql.model.ModelMutationLogging.MODEL_MUTATION_LOGGER; @@ -35,7 +36,7 @@ public class DeleteRowsCoordinatorStandard implements DeleteRowsCoordinator { private final BasicBatchKey batchKey; private final MutationExecutorService mutationExecutorService; - private MutationOperationGroupSingle operationGroup; + private MutationOperationGroup operationGroup; public DeleteRowsCoordinatorStandard( CollectionMutationTarget mutationTarget, @@ -114,11 +115,11 @@ public void deleteRows(PersistentCollection collection, Object key, SharedSes } } - private MutationOperationGroupSingle createOperationGroup() { + private MutationOperationGroup createOperationGroup() { assert mutationTarget.getTargetPart() != null; assert mutationTarget.getTargetPart().getKeyDescriptor() != null; final JdbcMutationOperation operation = rowMutationOperations.getDeleteRowOperation(); - return new MutationOperationGroupSingle( MutationType.DELETE, mutationTarget, operation ); + return MutationOperationGroupFactory.singleOperation( MutationType.DELETE, mutationTarget, operation ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/DeleteRowsCoordinatorTablePerSubclass.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/DeleteRowsCoordinatorTablePerSubclass.java index 89d6e9a8f0..1d43e7ba96 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/DeleteRowsCoordinatorTablePerSubclass.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/DeleteRowsCoordinatorTablePerSubclass.java @@ -7,12 +7,11 @@ package org.hibernate.persister.collection.mutation; import java.util.Iterator; -import java.util.function.Supplier; import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey; -import org.hibernate.engine.jdbc.batch.spi.BatchKey; import org.hibernate.engine.jdbc.mutation.MutationExecutor; +import org.hibernate.sql.model.internal.MutationOperationGroupFactory; import org.hibernate.engine.jdbc.mutation.spi.BatchKeyAccess; import org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService; import org.hibernate.engine.spi.EntityEntry; @@ -22,8 +21,8 @@ import org.hibernate.persister.collection.OneToManyPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.service.ServiceRegistry; +import org.hibernate.sql.model.MutationOperationGroup; import org.hibernate.sql.model.MutationType; -import org.hibernate.sql.model.internal.MutationOperationGroupSingle; import org.hibernate.sql.model.jdbc.JdbcMutationOperation; import static org.hibernate.sql.model.ModelMutationLogging.MODEL_MUTATION_LOGGER; @@ -136,7 +135,7 @@ private SubclassEntry getSubclassEntry(EntityPersister elementPersister) { ); } - private MutationOperationGroupSingle createOperationGroup(EntityPersister elementPersister) { + private MutationOperationGroup createOperationGroup(EntityPersister elementPersister) { assert mutationTarget.getTargetPart() != null; assert mutationTarget.getTargetPart().getKeyDescriptor() != null; @@ -154,16 +153,16 @@ private MutationOperationGroupSingle createOperationGroup(EntityPersister elemen collectionTableMapping.getDeleteRowDetails() ) ); - return new MutationOperationGroupSingle( MutationType.DELETE, mutationTarget, operation ); + return MutationOperationGroupFactory.singleOperation( MutationType.DELETE, mutationTarget, operation ); } private static class SubclassEntry { private final BatchKeyAccess batchKeySupplier; - private final MutationOperationGroupSingle operationGroup; + private final MutationOperationGroup operationGroup; - public SubclassEntry(BatchKeyAccess batchKeySupplier, MutationOperationGroupSingle operationGroup) { + public SubclassEntry(BatchKeyAccess batchKeySupplier, MutationOperationGroup operationGroup) { this.batchKeySupplier = batchKeySupplier; this.operationGroup = operationGroup; } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/InsertRowsCoordinatorStandard.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/InsertRowsCoordinatorStandard.java index f535308569..02da28cab2 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/InsertRowsCoordinatorStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/InsertRowsCoordinatorStandard.java @@ -12,13 +12,14 @@ import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey; import org.hibernate.engine.jdbc.mutation.JdbcValueBindings; import org.hibernate.engine.jdbc.mutation.MutationExecutor; +import org.hibernate.sql.model.internal.MutationOperationGroupFactory; import org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.service.ServiceRegistry; +import org.hibernate.sql.model.MutationOperationGroup; import org.hibernate.sql.model.MutationType; -import org.hibernate.sql.model.internal.MutationOperationGroupSingle; import org.hibernate.sql.model.jdbc.JdbcMutationOperation; import static org.hibernate.sql.model.ModelMutationLogging.MODEL_MUTATION_LOGGER; @@ -34,7 +35,7 @@ public class InsertRowsCoordinatorStandard implements InsertRowsCoordinator { private final BasicBatchKey batchKey; private final MutationExecutorService mutationExecutorService; - private MutationOperationGroupSingle operationGroup; + private MutationOperationGroup operationGroup; public InsertRowsCoordinatorStandard( CollectionMutationTarget mutationTarget, @@ -128,11 +129,11 @@ public void insertRows( } } - private MutationOperationGroupSingle createOperationGroup() { + private MutationOperationGroup createOperationGroup() { assert mutationTarget.getTargetPart() != null; assert mutationTarget.getTargetPart().getKeyDescriptor() != null; final JdbcMutationOperation operation = rowMutationOperations.getInsertRowOperation(); - return new MutationOperationGroupSingle( MutationType.INSERT, mutationTarget, operation ); + return MutationOperationGroupFactory.singleOperation( MutationType.INSERT, mutationTarget, operation ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/InsertRowsCoordinatorTablePerSubclass.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/InsertRowsCoordinatorTablePerSubclass.java index 54f7cd1166..3e547d40c5 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/InsertRowsCoordinatorTablePerSubclass.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/InsertRowsCoordinatorTablePerSubclass.java @@ -11,6 +11,7 @@ import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey; import org.hibernate.engine.jdbc.mutation.MutationExecutor; +import org.hibernate.sql.model.internal.MutationOperationGroupFactory; import org.hibernate.engine.jdbc.mutation.spi.BatchKeyAccess; import org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService; import org.hibernate.engine.spi.EntityEntry; @@ -20,8 +21,8 @@ import org.hibernate.persister.collection.OneToManyPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.service.ServiceRegistry; +import org.hibernate.sql.model.MutationOperationGroup; import org.hibernate.sql.model.MutationType; -import org.hibernate.sql.model.internal.MutationOperationGroupSingle; import org.hibernate.sql.model.jdbc.JdbcMutationOperation; import static org.hibernate.sql.model.ModelMutationLogging.MODEL_MUTATION_LOGGER; @@ -43,7 +44,10 @@ public InsertRowsCoordinatorTablePerSubclass( ServiceRegistry serviceRegistry) { this.mutationTarget = mutationTarget; this.rowMutationOperations = rowMutationOperations; - this.subclassEntries = new SubclassEntry[mutationTarget.getElementPersister().getRootEntityDescriptor().getSubclassEntityNames().size()]; + this.subclassEntries = new SubclassEntry[mutationTarget.getElementPersister() + .getRootEntityDescriptor() + .getSubclassEntityNames() + .size()]; this.mutationExecutorService = serviceRegistry.getService( MutationExecutorService.class ); } @@ -120,7 +124,11 @@ public void insertRows( entryCount++; } - MODEL_MUTATION_LOGGER.debugf( "Done inserting `%s` collection rows : %s", entryCount, mutationTarget.getRolePath() ); + MODEL_MUTATION_LOGGER.debugf( + "Done inserting `%s` collection rows : %s", + entryCount, + mutationTarget.getRolePath() + ); } finally { @@ -145,7 +153,7 @@ private SubclassEntry getSubclassEntry(EntityPersister elementPersister) { ); } - private MutationOperationGroupSingle createOperationGroup(EntityPersister elementPersister) { + private MutationOperationGroup createOperationGroup(EntityPersister elementPersister) { assert mutationTarget.getTargetPart() != null; assert mutationTarget.getTargetPart().getKeyDescriptor() != null; @@ -163,16 +171,16 @@ private MutationOperationGroupSingle createOperationGroup(EntityPersister elemen collectionTableMapping.getDeleteRowDetails() ) ); - return new MutationOperationGroupSingle( MutationType.INSERT, mutationTarget, operation ); + return MutationOperationGroupFactory.singleOperation( MutationType.INSERT, mutationTarget, operation ); } private static class SubclassEntry { private final BatchKeyAccess batchKeySupplier; - private final MutationOperationGroupSingle operationGroup; + private final MutationOperationGroup operationGroup; - public SubclassEntry(BatchKeyAccess batchKeySupplier, MutationOperationGroupSingle operationGroup) { + public SubclassEntry(BatchKeyAccess batchKeySupplier, MutationOperationGroup operationGroup) { this.batchKeySupplier = batchKeySupplier; this.operationGroup = operationGroup; } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/RemoveCoordinatorStandard.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/RemoveCoordinatorStandard.java index 552da59fd1..71787b50dd 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/RemoveCoordinatorStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/RemoveCoordinatorStandard.java @@ -9,13 +9,14 @@ import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey; import org.hibernate.engine.jdbc.mutation.JdbcValueBindings; import org.hibernate.engine.jdbc.mutation.MutationExecutor; +import org.hibernate.sql.model.internal.MutationOperationGroupFactory; import org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; import org.hibernate.service.ServiceRegistry; +import org.hibernate.sql.model.MutationOperationGroup; import org.hibernate.sql.model.MutationType; import org.hibernate.sql.model.ast.MutatingTableReference; -import org.hibernate.sql.model.internal.MutationOperationGroupSingle; import org.hibernate.sql.model.jdbc.JdbcMutationOperation; import static org.hibernate.sql.model.ModelMutationLogging.MODEL_MUTATION_LOGGER; @@ -33,7 +34,7 @@ public class RemoveCoordinatorStandard implements RemoveCoordinator { private final BasicBatchKey batchKey; private final MutationExecutorService mutationExecutorService; - private MutationOperationGroupSingle operationGroup; + private MutationOperationGroup operationGroup; /** * Creates the coordinator. @@ -69,7 +70,7 @@ public String getSqlString() { operationGroup = buildOperationGroup(); } - final JdbcMutationOperation operation = operationGroup.getSingleOperation(); + final JdbcMutationOperation operation = (JdbcMutationOperation) operationGroup.getSingleOperation(); return operation.getSqlString(); } @@ -119,7 +120,7 @@ public void deleteAllRows(Object key, SharedSessionContractImplementor session) } } - private MutationOperationGroupSingle buildOperationGroup() { + private MutationOperationGroup buildOperationGroup() { assert mutationTarget.getTargetPart() != null; assert mutationTarget.getTargetPart().getKeyDescriptor() != null; @@ -130,7 +131,7 @@ private MutationOperationGroupSingle buildOperationGroup() { final CollectionTableMapping tableMapping = mutationTarget.getCollectionTableMapping(); final MutatingTableReference tableReference = new MutatingTableReference( tableMapping ); - return new MutationOperationGroupSingle( + return MutationOperationGroupFactory.singleOperation( MutationType.DELETE, mutationTarget, operationProducer.createOperation( tableReference ) diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/RemoveCoordinatorTablePerSubclass.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/RemoveCoordinatorTablePerSubclass.java index 1ee0b4de94..83e4135699 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/RemoveCoordinatorTablePerSubclass.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/RemoveCoordinatorTablePerSubclass.java @@ -9,6 +9,7 @@ import java.util.Collection; import org.hibernate.engine.jdbc.mutation.MutationExecutor; +import org.hibernate.sql.model.internal.MutationOperationGroupFactory; import org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.metamodel.mapping.EntityMappingType; @@ -16,9 +17,9 @@ import org.hibernate.persister.collection.OneToManyPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.service.ServiceRegistry; +import org.hibernate.sql.model.MutationOperationGroup; import org.hibernate.sql.model.MutationType; import org.hibernate.sql.model.ast.MutatingTableReference; -import org.hibernate.sql.model.internal.MutationOperationGroupSingle; import static org.hibernate.sql.model.ModelMutationLogging.MODEL_MUTATION_LOGGER; import static org.hibernate.sql.model.ModelMutationLogging.MODEL_MUTATION_LOGGER_DEBUG_ENABLED; @@ -32,7 +33,7 @@ public class RemoveCoordinatorTablePerSubclass implements RemoveCoordinator { private final OperationProducer operationProducer; private final MutationExecutorService mutationExecutorService; - private MutationOperationGroupSingle[] operationGroups; + private MutationOperationGroup[] operationGroups; /** * Creates the coordinator. @@ -74,7 +75,7 @@ public void deleteAllRows(Object key, SharedSessionContractImplementor session) ); } - MutationOperationGroupSingle[] operationGroups = this.operationGroups; + MutationOperationGroup[] operationGroups = this.operationGroups; if ( operationGroups == null ) { // delayed creation of the operation-group operationGroups = this.operationGroups = buildOperationGroups(); @@ -82,7 +83,7 @@ public void deleteAllRows(Object key, SharedSessionContractImplementor session) final ForeignKeyDescriptor fkDescriptor = mutationTarget.getTargetPart().getKeyDescriptor(); - for ( MutationOperationGroupSingle operationGroup : operationGroups ) { + for ( MutationOperationGroup operationGroup : operationGroups ) { final MutationExecutor mutationExecutor = mutationExecutorService.createExecutor( () -> null, operationGroup, @@ -113,11 +114,11 @@ public void deleteAllRows(Object key, SharedSessionContractImplementor session) } } - private MutationOperationGroupSingle[] buildOperationGroups() { + private MutationOperationGroup[] buildOperationGroups() { final Collection subMappingTypes = mutationTarget.getElementPersister() .getRootEntityDescriptor() .getSubMappingTypes(); - final MutationOperationGroupSingle[] operationGroups = new MutationOperationGroupSingle[subMappingTypes.size()]; + final MutationOperationGroup[] operationGroups = new MutationOperationGroup[subMappingTypes.size()]; int i = 0; for ( EntityMappingType subMappingType : subMappingTypes ) { operationGroups[i++] = buildOperationGroup( subMappingType.getEntityPersister() ); @@ -125,7 +126,7 @@ private MutationOperationGroupSingle[] buildOperationGroups() { return operationGroups; } - private MutationOperationGroupSingle buildOperationGroup(EntityPersister elementPersister) { + private MutationOperationGroup buildOperationGroup(EntityPersister elementPersister) { assert mutationTarget.getTargetPart() != null; assert mutationTarget.getTargetPart().getKeyDescriptor() != null; @@ -148,7 +149,7 @@ private MutationOperationGroupSingle buildOperationGroup(EntityPersister element ) ); - return new MutationOperationGroupSingle( + return MutationOperationGroupFactory.singleOperation( MutationType.DELETE, mutationTarget, operationProducer.createOperation( tableReference ) diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/UpdateRowsCoordinatorOneToMany.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/UpdateRowsCoordinatorOneToMany.java index 1b6febe9ec..551410f821 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/UpdateRowsCoordinatorOneToMany.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/UpdateRowsCoordinatorOneToMany.java @@ -12,12 +12,13 @@ import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey; import org.hibernate.engine.jdbc.mutation.JdbcValueBindings; import org.hibernate.engine.jdbc.mutation.MutationExecutor; +import org.hibernate.sql.model.internal.MutationOperationGroupFactory; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.sql.model.MutationOperationGroup; import org.hibernate.sql.model.MutationType; -import org.hibernate.sql.model.internal.MutationOperationGroupSingle; import org.hibernate.sql.model.jdbc.JdbcMutationOperation; /** @@ -26,8 +27,8 @@ public class UpdateRowsCoordinatorOneToMany extends AbstractUpdateRowsCoordinator { private final RowMutationOperations rowMutationOperations; - private MutationOperationGroupSingle deleteOperationGroup; - private MutationOperationGroupSingle insertOperationGroup; + private MutationOperationGroup deleteOperationGroup; + private MutationOperationGroup insertOperationGroup; public UpdateRowsCoordinatorOneToMany( CollectionMutationTarget mutationTarget, @@ -58,7 +59,7 @@ private void deleteRows(Object key, PersistentCollection collection, SharedSe return; } - final MutationOperationGroupSingle operationGroup = resolveDeleteGroup(); + final MutationOperationGroup operationGroup = resolveDeleteGroup(); final MutationExecutor mutationExecutor = mutationExecutorService.createExecutor( () -> new BasicBatchKey( getMutationTarget().getRolePath() + "#UPDATE-DELETE" ), operationGroup, @@ -96,12 +97,12 @@ private void deleteRows(Object key, PersistentCollection collection, SharedSe } } - private MutationOperationGroupSingle resolveDeleteGroup() { + private MutationOperationGroup resolveDeleteGroup() { if ( deleteOperationGroup == null ) { final JdbcMutationOperation operation = rowMutationOperations.getDeleteRowOperation(); assert operation != null; - deleteOperationGroup = new MutationOperationGroupSingle( MutationType.DELETE, getMutationTarget(), operation ); + deleteOperationGroup = MutationOperationGroupFactory.singleOperation( MutationType.DELETE, getMutationTarget(), operation ); } return deleteOperationGroup; @@ -115,7 +116,7 @@ private int insertRows(Object key, PersistentCollection collection, SharedSes return -1; } - final MutationOperationGroupSingle operationGroup = resolveInsertGroup(); + final MutationOperationGroup operationGroup = resolveInsertGroup(); final MutationExecutor mutationExecutor = mutationExecutorService.createExecutor( () -> new BasicBatchKey( getMutationTarget().getRolePath() + "#UPDATE-INSERT" ), operationGroup, @@ -154,12 +155,12 @@ private int insertRows(Object key, PersistentCollection collection, SharedSes } } - private MutationOperationGroupSingle resolveInsertGroup() { + private MutationOperationGroup resolveInsertGroup() { if ( insertOperationGroup == null ) { final JdbcMutationOperation operation = rowMutationOperations.getInsertRowOperation(); assert operation != null; - insertOperationGroup = new MutationOperationGroupSingle( MutationType.INSERT, getMutationTarget(), operation ); + insertOperationGroup = MutationOperationGroupFactory.singleOperation( MutationType.INSERT, getMutationTarget(), operation ); } return insertOperationGroup; diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/UpdateRowsCoordinatorStandard.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/UpdateRowsCoordinatorStandard.java index 9ff1d1ad5b..e4cd2d6a9a 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/UpdateRowsCoordinatorStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/UpdateRowsCoordinatorStandard.java @@ -13,13 +13,12 @@ import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey; import org.hibernate.engine.jdbc.mutation.MutationExecutor; +import org.hibernate.sql.model.internal.MutationOperationGroupFactory; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.metamodel.mapping.PluralAttributeMapping; +import org.hibernate.sql.model.MutationOperationGroup; import org.hibernate.sql.model.MutationType; -import org.hibernate.sql.model.internal.AbstractMutationOperationGroup; -import org.hibernate.sql.model.internal.MutationOperationGroupNone; -import org.hibernate.sql.model.internal.MutationOperationGroupSingle; import org.hibernate.sql.model.jdbc.JdbcMutationOperation; /** @@ -32,7 +31,7 @@ public class UpdateRowsCoordinatorStandard extends AbstractUpdateRowsCoordinator implements UpdateRowsCoordinator { private final RowMutationOperations rowMutationOperations; - private AbstractMutationOperationGroup operationGroup; + private MutationOperationGroup operationGroup; public UpdateRowsCoordinatorStandard( CollectionMutationTarget mutationTarget, @@ -44,7 +43,7 @@ public UpdateRowsCoordinatorStandard( @Override protected int doUpdate(Object key, PersistentCollection collection, SharedSessionContractImplementor session) { - final AbstractMutationOperationGroup operationGroup = getOperationGroup(); + final MutationOperationGroup operationGroup = getOperationGroup(); final MutationExecutor mutationExecutor = mutationExecutorService.createExecutor( () -> new BasicBatchKey( getMutationTarget().getRolePath() + "#UPDATE" ), @@ -144,21 +143,14 @@ private boolean processRow( } } - protected AbstractMutationOperationGroup getOperationGroup() { + protected MutationOperationGroup getOperationGroup() { if ( operationGroup == null ) { final JdbcMutationOperation updateRowOperation = rowMutationOperations.getUpdateRowOperation(); if ( updateRowOperation == null ) { - operationGroup = new MutationOperationGroupNone( - MutationType.UPDATE, - getMutationTarget() - ); + operationGroup = MutationOperationGroupFactory.noOperations( MutationType.UPDATE, getMutationTarget() ); } else { - operationGroup = new MutationOperationGroupSingle( - MutationType.UPDATE, - getMutationTarget(), - updateRowOperation - ); + operationGroup = MutationOperationGroupFactory.singleOperation( MutationType.UPDATE, getMutationTarget(), updateRowOperation ); } } return operationGroup; diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/UpdateRowsCoordinatorTablePerSubclass.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/UpdateRowsCoordinatorTablePerSubclass.java index e70ee2719b..ae075c55df 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/UpdateRowsCoordinatorTablePerSubclass.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/mutation/UpdateRowsCoordinatorTablePerSubclass.java @@ -11,6 +11,7 @@ import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey; import org.hibernate.engine.jdbc.mutation.MutationExecutor; +import org.hibernate.sql.model.internal.MutationOperationGroupFactory; import org.hibernate.engine.jdbc.mutation.spi.BatchKeyAccess; import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.SessionFactoryImplementor; @@ -19,8 +20,8 @@ import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.OneToManyPersister; import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.sql.model.MutationOperationGroup; import org.hibernate.sql.model.MutationType; -import org.hibernate.sql.model.internal.MutationOperationGroupSingle; import org.hibernate.sql.model.jdbc.JdbcMutationOperation; /** @@ -124,7 +125,7 @@ private SubclassEntry getDeleteSubclassEntry( EntityPersister elementPersister) ); } - private MutationOperationGroupSingle resolveDeleteGroup(EntityPersister elementPersister) { + private MutationOperationGroup resolveDeleteGroup(EntityPersister elementPersister) { final CollectionTableMapping collectionTableMapping = getMutationTarget().getCollectionTableMapping(); final JdbcMutationOperation operation = rowMutationOperations.getDeleteRowOperation( new CollectionTableMapping( @@ -140,7 +141,7 @@ private MutationOperationGroupSingle resolveDeleteGroup(EntityPersister elementP ) ); - return new MutationOperationGroupSingle( MutationType.DELETE, getMutationTarget(), operation ); + return MutationOperationGroupFactory.singleOperation( MutationType.DELETE, getMutationTarget(), operation ); } private int insertRows(Object key, PersistentCollection collection, SharedSessionContractImplementor session) { @@ -213,7 +214,7 @@ private SubclassEntry getInsertSubclassEntry( EntityPersister elementPersister) ); } - private MutationOperationGroupSingle resolveInsertGroup(EntityPersister elementPersister) { + private MutationOperationGroup resolveInsertGroup(EntityPersister elementPersister) { final CollectionTableMapping collectionTableMapping = getMutationTarget().getCollectionTableMapping(); final JdbcMutationOperation operation = rowMutationOperations.getInsertRowOperation( new CollectionTableMapping( @@ -229,16 +230,16 @@ private MutationOperationGroupSingle resolveInsertGroup(EntityPersister elementP ) ); - return new MutationOperationGroupSingle( MutationType.INSERT, getMutationTarget(), operation ); + return MutationOperationGroupFactory.singleOperation( MutationType.INSERT, getMutationTarget(), operation ); } private static class SubclassEntry { private final BatchKeyAccess batchKeySupplier; - private final MutationOperationGroupSingle operationGroup; + private final MutationOperationGroup operationGroup; - public SubclassEntry(BatchKeyAccess batchKeySupplier, MutationOperationGroupSingle operationGroup) { + public SubclassEntry(BatchKeyAccess batchKeySupplier, MutationOperationGroup operationGroup) { this.batchKeySupplier = batchKeySupplier; this.operationGroup = operationGroup; } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/AbstractMutationCoordinator.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/AbstractMutationCoordinator.java index 633e32912e..b9452122b2 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/AbstractMutationCoordinator.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/AbstractMutationCoordinator.java @@ -6,8 +6,6 @@ */ package org.hibernate.persister.entity.mutation; -import java.util.List; - import org.hibernate.Internal; import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.batch.spi.BatchKey; @@ -27,14 +25,10 @@ import org.hibernate.sql.model.MutationOperationGroup; import org.hibernate.sql.model.ValuesAnalysis; import org.hibernate.sql.model.ast.MutationGroup; +import org.hibernate.sql.model.ast.TableMutation; import org.hibernate.sql.model.ast.builder.ColumnValuesTableMutationBuilder; import org.hibernate.sql.model.ast.builder.MutationGroupBuilder; -import org.hibernate.sql.model.internal.MutationOperationGroupNone; -import org.hibernate.sql.model.internal.MutationOperationGroupSingle; -import org.hibernate.sql.model.internal.MutationOperationGroupStandard; -import org.hibernate.sql.model.jdbc.JdbcMutationOperation; - -import static org.hibernate.internal.util.collections.CollectionHelper.arrayList; +import org.hibernate.sql.model.internal.MutationOperationGroupFactory; /** * Base support for coordinating mutations against an entity @@ -85,29 +79,38 @@ protected MutationOperationGroup createOperationGroup(ValuesAnalysis valuesAnaly final int numberOfTableMutations = mutationGroup.getNumberOfTableMutations(); switch ( numberOfTableMutations ) { case 0: - return new MutationOperationGroupNone( mutationGroup ); + return MutationOperationGroupFactory.noOperations( mutationGroup ); case 1: { final MutationOperation operation = mutationGroup.getSingleTableMutation() .createMutationOperation( valuesAnalysis, factory() ); return operation == null - ? new MutationOperationGroupNone( mutationGroup ) - : new MutationOperationGroupSingle( mutationGroup, (JdbcMutationOperation) operation ); + ? MutationOperationGroupFactory.noOperations( mutationGroup ) + : MutationOperationGroupFactory.singleOperation( mutationGroup, operation ); } default: { - final List operations = arrayList( numberOfTableMutations ); - mutationGroup.forEachTableMutation( (integer, tableMutation) -> { + MutationOperation[] operations = new MutationOperation[numberOfTableMutations]; + int outputIndex = 0; + int skipped = 0; + for ( int i = 0; i < mutationGroup.getNumberOfTableMutations(); i++ ) { + final TableMutation tableMutation = mutationGroup.getTableMutation( i ); final MutationOperation operation = tableMutation.createMutationOperation( valuesAnalysis, factory ); if ( operation != null ) { - operations.add( operation ); + operations[outputIndex++] = operation; } else { + skipped++; ModelMutationLogging.MODEL_MUTATION_LOGGER.debugf( "Skipping table update - %s", tableMutation.getTableName() ); } - } ); - return new MutationOperationGroupStandard( mutationGroup.getMutationType(), entityPersister, operations ); + } + if ( skipped != 0 ) { + final MutationOperation[] trimmed = new MutationOperation[outputIndex]; + System.arraycopy( operations, 0, trimmed, 0, outputIndex ); + operations = trimmed; + } + return MutationOperationGroupFactory.manyOperations( mutationGroup.getMutationType(), entityPersister, operations ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/InsertCoordinator.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/InsertCoordinator.java index 68be0e5304..1f139cf0ac 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/InsertCoordinator.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/InsertCoordinator.java @@ -114,7 +114,8 @@ public Object coordinateInsert( } protected void preInsertInMemoryValueGeneration(Object[] values, Object entity, SharedSessionContractImplementor session) { - final EntityMetamodel entityMetamodel = entityPersister().getEntityMetamodel(); + final AbstractEntityPersister persister = entityPersister(); + final EntityMetamodel entityMetamodel = persister.getEntityMetamodel(); if ( entityMetamodel.hasPreInsertGeneratedValues() ) { final Generator[] generators = entityMetamodel.getGenerators(); for ( int i = 0; i < generators.length; i++ ) { @@ -123,7 +124,7 @@ protected void preInsertInMemoryValueGeneration(Object[] values, Object entity, && !generator.generatedOnExecution() && generator.generatesOnInsert() ) { values[i] = ( (BeforeExecutionGenerator) generator ).generate( session, entity, values[i], INSERT ); - entityPersister().setPropertyValue( entity, i, values[i] ); + persister.setPropertyValue( entity, i, values[i] ); } } } @@ -214,12 +215,12 @@ protected void decomposeForInsert( } } - for ( int position = 0; position < mutationGroup.getNumberOfOperations(); position++ ) { - final MutationOperation jdbcOperation = mutationGroup.getOperation( position ); - if ( id == null ) { - assert entityPersister().getIdentityInsertDelegate() != null; - } - else { + if ( id == null ) { + assert entityPersister().getIdentityInsertDelegate() != null; + } + else { + for ( int position = 0; position < mutationGroup.getNumberOfOperations(); position++ ) { + final MutationOperation jdbcOperation = mutationGroup.getOperation( position ); final EntityTableMapping tableDetails = (EntityTableMapping) jdbcOperation.getTableDetails(); breakDownJdbcValue( id, session, jdbcValueBindings, tableDetails ); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/UpdateCoordinatorNoOp.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/UpdateCoordinatorNoOp.java index 75c6475f81..7c6be40137 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/UpdateCoordinatorNoOp.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/UpdateCoordinatorNoOp.java @@ -6,11 +6,11 @@ */ package org.hibernate.persister.entity.mutation; +import org.hibernate.sql.model.internal.MutationOperationGroupFactory; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.persister.entity.AbstractEntityPersister; import org.hibernate.sql.model.MutationOperationGroup; import org.hibernate.sql.model.MutationType; -import org.hibernate.sql.model.internal.MutationOperationGroupNone; /** * @author Steve Ebersole @@ -19,7 +19,7 @@ public class UpdateCoordinatorNoOp implements UpdateCoordinator { private final MutationOperationGroup operationGroup; public UpdateCoordinatorNoOp(AbstractEntityPersister entityPersister) { - operationGroup = new MutationOperationGroupNone( MutationType.UPDATE, entityPersister ); + operationGroup = MutationOperationGroupFactory.noOperations( MutationType.UPDATE, entityPersister ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/UpdateCoordinatorStandard.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/UpdateCoordinatorStandard.java index d5493d7ef4..2cca6e7595 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/UpdateCoordinatorStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/UpdateCoordinatorStandard.java @@ -22,6 +22,7 @@ import org.hibernate.engine.jdbc.mutation.JdbcValueBindings; import org.hibernate.engine.jdbc.mutation.MutationExecutor; import org.hibernate.engine.jdbc.mutation.ParameterUsage; +import org.hibernate.sql.model.internal.MutationOperationGroupFactory; import org.hibernate.engine.jdbc.mutation.internal.MutationQueryOptions; import org.hibernate.engine.jdbc.mutation.internal.NoBatchKeyAccess; import org.hibernate.engine.jdbc.mutation.spi.BatchKeyAccess; @@ -52,7 +53,6 @@ import org.hibernate.sql.model.ast.builder.TableUpdateBuilder; import org.hibernate.sql.model.ast.builder.TableUpdateBuilderSkipped; import org.hibernate.sql.model.ast.builder.TableUpdateBuilderStandard; -import org.hibernate.sql.model.internal.MutationOperationGroupSingle; import org.hibernate.sql.model.jdbc.JdbcMutationOperation; import org.hibernate.tuple.entity.EntityMetamodel; @@ -1639,7 +1639,7 @@ private MutationOperationGroup buildVersionUpdateGroup() { .buildModelMutationTranslator( updateBuilder.buildMutation(), factory() ) .translate( null, MutationQueryOptions.INSTANCE ); - return new MutationOperationGroupSingle( MutationType.UPDATE, entityPersister(), jdbcMutation ); + return MutationOperationGroupFactory.singleOperation( MutationType.UPDATE, entityPersister(), jdbcMutation ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/model/MutationOperationGroup.java b/hibernate-core/src/main/java/org/hibernate/sql/model/MutationOperationGroup.java index 20fa561dfd..68cdb94c45 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/model/MutationOperationGroup.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/model/MutationOperationGroup.java @@ -6,6 +6,8 @@ */ package org.hibernate.sql.model; +import org.hibernate.engine.jdbc.mutation.internal.EntityMutationOperationGroup; + /** * Group of {@link MutationOperation} references for a specific * logical operation (target + type) @@ -22,7 +24,7 @@ public interface MutationOperationGroup { /** * The model-part being mutated */ - MutationTarget getMutationTarget(); + MutationTarget getMutationTarget(); /** * Number of operations in this group @@ -48,4 +50,12 @@ public interface MutationOperationGroup { */ MutationOperation getOperation(String tableName); + /** + * Attempt to cast to the frequently uses subtype EntityMutationOperationGroup; + * returns null if this is not possible. + * @return + */ + default EntityMutationOperationGroup asEntityMutationOperationGroup() { + return null; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/model/ast/MutationGroup.java b/hibernate-core/src/main/java/org/hibernate/sql/model/ast/MutationGroup.java index 077b45a9cf..5f56d31868 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/model/ast/MutationGroup.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/model/ast/MutationGroup.java @@ -8,6 +8,7 @@ import java.util.function.BiConsumer; +import org.hibernate.sql.model.MutationOperation; import org.hibernate.sql.model.MutationTarget; import org.hibernate.sql.model.MutationType; @@ -26,7 +27,11 @@ public interface MutationGroup { TableMutation getSingleTableMutation(); - TableMutation getTableMutation(String tableName); + @Deprecated(forRemoval = true) + > M getTableMutation(String tableName); - void forEachTableMutation(BiConsumer action); + @Deprecated(forRemoval = true) + > void forEachTableMutation(BiConsumer action); + + TableMutation getTableMutation(int i); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/model/internal/AbstractMutationOperationGroup.java b/hibernate-core/src/main/java/org/hibernate/sql/model/internal/AbstractMutationOperationGroup.java deleted file mode 100644 index aabd7628ae..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/sql/model/internal/AbstractMutationOperationGroup.java +++ /dev/null @@ -1,34 +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.model.internal; - -import org.hibernate.sql.model.MutationOperationGroup; -import org.hibernate.sql.model.MutationTarget; -import org.hibernate.sql.model.MutationType; - -/** - * @author Steve Ebersole - */ -public abstract class AbstractMutationOperationGroup implements MutationOperationGroup { - private final MutationType mutationType; - private final MutationTarget mutationTarget; - - public AbstractMutationOperationGroup(MutationType mutationType, MutationTarget mutationTarget) { - this.mutationType = mutationType; - this.mutationTarget = mutationTarget; - } - - @Override - public MutationType getMutationType() { - return mutationType; - } - - @Override - public MutationTarget getMutationTarget() { - return mutationTarget; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/model/internal/EntityMutationOperationGroupStandard.java b/hibernate-core/src/main/java/org/hibernate/sql/model/internal/EntityMutationOperationGroupStandard.java new file mode 100644 index 0000000000..b2b7cde122 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/model/internal/EntityMutationOperationGroupStandard.java @@ -0,0 +1,106 @@ +/* + * 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.model.internal; + +import java.util.Locale; + +import org.hibernate.engine.jdbc.mutation.internal.EntityMutationOperationGroup; +import org.hibernate.persister.entity.mutation.EntityMutationTarget; +import org.hibernate.sql.model.MutationOperation; +import org.hibernate.sql.model.MutationType; + +public class EntityMutationOperationGroupStandard implements EntityMutationOperationGroup { + + private static final MutationOperation[] EMPTY = new MutationOperation[0]; + + private final MutationType mutationType; + private final EntityMutationTarget mutationTarget; + private final MutationOperation[] operations; + + /** + * Intentionally package private: use {@link MutationOperationGroupFactory}. + * Constructor for when there are no operations. + * @param mutationType + * @param mutationTarget + */ + EntityMutationOperationGroupStandard(MutationType mutationType, EntityMutationTarget mutationTarget) { + this( mutationType, mutationTarget, EMPTY ); + } + + /** + * Intentionally package private: use {@link MutationOperationGroupFactory}. + * Constructor for when there's a single operation. + * @param mutationType + * @param mutationTarget + * @param operation + */ + EntityMutationOperationGroupStandard(MutationType mutationType, EntityMutationTarget mutationTarget, MutationOperation operation) { + this( mutationType, mutationTarget, new MutationOperation[]{ operation } ); + } + + /** + * Intentionally package private: use {@link MutationOperationGroupFactory}. + * Constructor for when there's multiple operations. + * @param mutationType + * @param mutationTarget + * @param operations + */ + EntityMutationOperationGroupStandard(MutationType mutationType, EntityMutationTarget mutationTarget, MutationOperation[] operations) { + this.mutationType = mutationType; + this.mutationTarget = mutationTarget; + this.operations = operations; + } + + @Override + public MutationType getMutationType() { + return mutationType; + } + + @Override + public EntityMutationTarget getMutationTarget() { + return mutationTarget; + } + + @Override + public int getNumberOfOperations() { + return operations.length; + } + + @Override + public MutationOperation getSingleOperation() { + if ( operations.length == 1 ) { + return operations[0]; + } + else { + throw new IllegalStateException( + String.format( + Locale.ROOT, + "Group contains multiple table mutations - %s : %s ", + getMutationType().name(), + getMutationTarget().getNavigableRole() + ) + ); + } + } + + @Override + public MutationOperation getOperation(int idx) { + return operations[idx]; + } + + @Override + public MutationOperation getOperation(final String tableName) { + for ( int i = 0; i < operations.length; i++ ) { + final MutationOperation operation = operations[i]; + if ( operation.getTableDetails().getTableName().equals( tableName ) ) { + return operation; + } + } + return null; + } + +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationGroupNone.java b/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationGroupNone.java index b705ce4d1f..13d4b699a5 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationGroupNone.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationGroupNone.java @@ -9,6 +9,7 @@ import java.util.Locale; import java.util.function.BiConsumer; +import org.hibernate.sql.model.MutationOperation; import org.hibernate.sql.model.MutationTarget; import org.hibernate.sql.model.MutationType; import org.hibernate.sql.model.ast.MutationGroup; @@ -55,7 +56,12 @@ public TableMutation getTableMutation(String tableName) { } @Override - public void forEachTableMutation(BiConsumer action) { + public > void forEachTableMutation(BiConsumer action) { + } + + @Override + public TableMutation getTableMutation(int i) { + return null; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationGroupSingle.java b/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationGroupSingle.java index 82d78f54b3..c55c039ee4 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationGroupSingle.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationGroupSingle.java @@ -9,6 +9,7 @@ import java.util.Locale; import java.util.function.BiConsumer; +import org.hibernate.sql.model.MutationOperation; import org.hibernate.sql.model.MutationTarget; import org.hibernate.sql.model.MutationType; import org.hibernate.sql.model.ast.MutationGroup; @@ -61,8 +62,14 @@ public TableMutation getTableMutation(String tableName) { } @Override - public void forEachTableMutation(BiConsumer action) { - action.accept( 0, tableMutation ); + public > void forEachTableMutation(BiConsumer action) { + //noinspection unchecked + action.accept( 0, (M) tableMutation ); + } + + @Override + public TableMutation getTableMutation(int i) { + return tableMutation; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationGroupStandard.java b/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationGroupStandard.java index 780ee07a50..9d82b5e7fe 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationGroupStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationGroupStandard.java @@ -9,6 +9,7 @@ import java.util.List; import java.util.function.BiConsumer; +import org.hibernate.sql.model.MutationOperation; import org.hibernate.sql.model.MutationTarget; import org.hibernate.sql.model.MutationType; import org.hibernate.sql.model.ast.MutationGroup; @@ -67,10 +68,16 @@ public TableMutation getTableMutation(String tableName) { } @Override - public void forEachTableMutation(BiConsumer action) { + public > void forEachTableMutation(BiConsumer action) { for ( int i = 0; i < tableMutationList.size(); i++ ) { - action.accept( i, tableMutationList.get( i ) ); + //noinspection unchecked + action.accept( i, (M)tableMutationList.get( i ) ); } } + @Override + public TableMutation getTableMutation(int i) { + return tableMutationList.get( i ); + } + } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationOperationGroupFactory.java b/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationOperationGroupFactory.java new file mode 100644 index 0000000000..1d7da2cf41 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationOperationGroupFactory.java @@ -0,0 +1,74 @@ +/* + * 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.model.internal; + +import org.hibernate.persister.entity.mutation.EntityMutationTarget; +import org.hibernate.sql.model.MutationOperation; +import org.hibernate.sql.model.MutationOperationGroup; +import org.hibernate.sql.model.MutationTarget; +import org.hibernate.sql.model.MutationType; +import org.hibernate.sql.model.ast.MutationGroup; + +public final class MutationOperationGroupFactory { + + public static MutationOperationGroup noOperations( + final MutationType mutationType, + final MutationTarget mutationTarget) { + if ( mutationTarget instanceof EntityMutationTarget ) { + return new EntityMutationOperationGroupStandard( + mutationType, + (EntityMutationTarget) mutationTarget + ); + } + else { + return new MutationOperationGroupStandard( + mutationType, + mutationTarget + ); + } + } + + public static MutationOperationGroup noOperations(final MutationGroup mutationGroup) { + return noOperations( mutationGroup.getMutationType(), mutationGroup.getMutationTarget() ); + } + + public static MutationOperationGroup singleOperation( + final MutationType mutationType, + final MutationTarget mutationTarget, + final MutationOperation operation) { + if ( mutationTarget instanceof EntityMutationTarget ) { + return new EntityMutationOperationGroupStandard( + mutationType, + (EntityMutationTarget) mutationTarget, + operation + ); + } + else { + return new MutationOperationGroupStandard( + mutationType, + mutationTarget, + operation + ); + } + } + + public static MutationOperationGroup singleOperation(final MutationGroup mutationGroup, final MutationOperation operation) { + return singleOperation( mutationGroup.getMutationType(), mutationGroup.getMutationTarget(), operation ); + } + + public static MutationOperationGroup manyOperations( + final MutationType mutationType, + final MutationTarget mutationTarget, + final MutationOperation[] operations) { + if ( mutationTarget instanceof EntityMutationTarget ) { + return new EntityMutationOperationGroupStandard( mutationType, (EntityMutationTarget) mutationTarget, operations ); + } + else { + return new MutationOperationGroupStandard( mutationType, mutationTarget, operations ); + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationOperationGroupNone.java b/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationOperationGroupNone.java deleted file mode 100644 index 4a691bd866..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationOperationGroupNone.java +++ /dev/null @@ -1,47 +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.model.internal; - -import org.hibernate.sql.model.MutationOperation; -import org.hibernate.sql.model.MutationTarget; -import org.hibernate.sql.model.MutationType; -import org.hibernate.sql.model.ast.MutationGroup; - -/** - * Specialized MutationOperationGroup for case of no operations - * - * @author Steve Ebersole - */ -public class MutationOperationGroupNone extends AbstractMutationOperationGroup { - public MutationOperationGroupNone(MutationType mutationType, MutationTarget mutationTarget) { - super( mutationType, mutationTarget ); - } - public MutationOperationGroupNone(MutationGroup mutationGroup) { - this( mutationGroup.getMutationType(), mutationGroup.getMutationTarget() ); - } - - @Override - public int getNumberOfOperations() { - return 0; - } - - @Override - public MutationOperation getSingleOperation() { - return null; - } - - @Override - public MutationOperation getOperation(int idx) { - throw new IndexOutOfBoundsException( idx ); - } - - @Override - public MutationOperation getOperation(String tableName) { - return null; - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationOperationGroupSingle.java b/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationOperationGroupSingle.java deleted file mode 100644 index fb7779efda..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationOperationGroupSingle.java +++ /dev/null @@ -1,67 +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.model.internal; - -import org.hibernate.sql.model.MutationOperation; -import org.hibernate.sql.model.MutationTarget; -import org.hibernate.sql.model.MutationType; -import org.hibernate.sql.model.ast.MutationGroup; -import org.hibernate.sql.model.jdbc.JdbcMutationOperation; - -import static org.hibernate.sql.model.ModelMutationLogging.MODEL_MUTATION_LOGGER; - -/** - * @author Steve Ebersole - */ -public class MutationOperationGroupSingle extends AbstractMutationOperationGroup { - - private final JdbcMutationOperation operation; - - public MutationOperationGroupSingle( - MutationType mutationType, - MutationTarget mutationTarget, - JdbcMutationOperation operation) { - super( mutationType, mutationTarget ); - this.operation = operation; - } - - public MutationOperationGroupSingle(MutationGroup mutationGroup, JdbcMutationOperation operation) { - this( mutationGroup.getMutationType(), mutationGroup.getMutationTarget(), operation ); - } - - @Override - public int getNumberOfOperations() { - return 1; - } - - @Override - public JdbcMutationOperation getSingleOperation() { - return operation; - } - - @Override - public MutationOperation getOperation(int idx) { - if ( idx != 0 ) { - throw new IndexOutOfBoundsException( idx ); - } - return operation; - } - - @Override - public MutationOperation getOperation(String tableName) { - if ( !tableName.equals( operation.getTableDetails().getTableName() ) ) { - MODEL_MUTATION_LOGGER.debugf( - "Unexpected table name mismatch : `%s` - `%s`", - tableName, - operation.getTableDetails().getTableName() - ); - } - - return operation; - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationOperationGroupStandard.java b/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationOperationGroupStandard.java index ddf3cc3767..1b8d455ca8 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationOperationGroupStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationOperationGroupStandard.java @@ -6,53 +6,100 @@ */ package org.hibernate.sql.model.internal; -import java.util.List; import java.util.Locale; import org.hibernate.sql.model.MutationOperation; +import org.hibernate.sql.model.MutationOperationGroup; import org.hibernate.sql.model.MutationTarget; import org.hibernate.sql.model.MutationType; /** * @author Steve Ebersole + * @author Sanne Grinovero */ -public class MutationOperationGroupStandard extends AbstractMutationOperationGroup { - private final List operations; +final class MutationOperationGroupStandard implements MutationOperationGroup { - public MutationOperationGroupStandard(MutationType mutationType, MutationTarget mutationTarget, List operations) { - super( mutationType, mutationTarget ); + private static final MutationOperation[] EMPTY = new MutationOperation[0]; + + private final MutationType mutationType; + private final MutationTarget mutationTarget; + private final MutationOperation[] operations; + + /** + * Intentionally package private: use {@link MutationOperationGroupFactory}. + * Constructor for when there are no operations. + * @param mutationType + * @param mutationTarget + */ + MutationOperationGroupStandard(MutationType mutationType, MutationTarget mutationTarget) { + this( mutationType, mutationTarget, EMPTY ); + } + + /** + * Intentionally package private: use {@link MutationOperationGroupFactory}. + * Constructor for when there's a single operation. + * @param mutationType + * @param mutationTarget + * @param operation + */ + MutationOperationGroupStandard(MutationType mutationType, MutationTarget mutationTarget, MutationOperation operation) { + this( mutationType, mutationTarget, new MutationOperation[]{ operation } ); + } + + /** + * Intentionally package private: use {@link MutationOperationGroupFactory}. + * Constructor for when there's multiple operations. + * @param mutationType + * @param mutationTarget + * @param operations + */ + MutationOperationGroupStandard(MutationType mutationType, MutationTarget mutationTarget, MutationOperation[] operations) { + this.mutationType = mutationType; + this.mutationTarget = mutationTarget; this.operations = operations; } + @Override + public MutationType getMutationType() { + return mutationType; + } + + @Override + public MutationTarget getMutationTarget() { + return mutationTarget; + } + @Override public int getNumberOfOperations() { - return operations.size(); + return operations.length; } @Override public MutationOperation getSingleOperation() { - if ( operations.size() == 1 ) { - return operations.get( 0 ); + if ( operations.length == 1 ) { + return operations[0]; + } + else { + throw new IllegalStateException( + String.format( + Locale.ROOT, + "Group contains multiple table mutations - %s : %s ", + getMutationType().name(), + getMutationTarget().getNavigableRole() + ) + ); } - throw new IllegalStateException( - String.format( - Locale.ROOT, - "Group contains multiple table mutations - %s : %s ", - getMutationType().name(), - getMutationTarget().getNavigableRole() - ) - ); } @Override public MutationOperation getOperation(int idx) { - return operations.get( idx ); + return operations[idx]; } @Override - public MutationOperation getOperation(String tableName) { - for ( int i = 0; i < operations.size(); i++ ) { - final MutationOperation operation = operations.get( i ); + public MutationOperation getOperation(final String tableName) { + for ( int i = 0; i < operations.length; i++ ) { + final MutationOperation operation = operations[i]; if ( operation.getTableDetails().getTableName().equals( tableName ) ) { return operation; }