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 000000000000..f93dc1af04e4 --- /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 c8826f8ad89b..6960be0dceea 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 @@ -60,8 +60,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, @@ -70,7 +70,7 @@ public MutationExecutorPostInsert(MutationOperationGroup mutationOperationGroup, ); this.mutationOperationGroup = mutationOperationGroup; - final PreparableMutationOperation identityInsertOperation = mutationOperationGroup.getOperation( mutationTarget.getIdentifierTableName() ); + final PreparableMutationOperation identityInsertOperation = (PreparableMutationOperation) mutationOperationGroup.getOperation( mutationTarget.getIdentifierTableName() ); this.identityInsertStatementDetails = ModelMutationHelper.identityPreparation( identityInsertOperation, session @@ -78,9 +78,8 @@ public MutationExecutorPostInsert(MutationOperationGroup mutationOperationGroup, List secondaryTableMutations = null; - final List operations = mutationOperationGroup.getOperations(); - for ( int i = 0; i < operations.size(); i++ ) { - final MutationOperation operation = operations.get( i ); + for ( int i = 0; i < mutationOperationGroup.getNumberOfOperations(); i++ ) { + final MutationOperation operation = mutationOperationGroup.getOperation( i ); if ( operation.getTableDetails().isIdentifierTable() ) { // the identifier table is handled via `identityInsertStatementDetails` 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 48f06c3dec22..6f0bc276b204 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 @@ -51,14 +51,14 @@ 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; - this.operation = mutationOperationGroup.getOperation( mutationTarget.getIdentifierTableName() ); + this.operation = (PreparableMutationOperation) mutationOperationGroup.getOperation( mutationTarget.getIdentifierTableName() ); this.identityInsertStatementDetails = identityPreparation( operation, session ); this.valueBindings = new JdbcValueBindingsImpl( diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/MutationExecutorStandard.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/MutationExecutorStandard.java index 437525bbec92..8de72f7c0aa7 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/MutationExecutorStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/MutationExecutorStandard.java @@ -11,7 +11,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.function.Supplier; import org.hibernate.engine.jdbc.batch.spi.Batch; import org.hibernate.engine.jdbc.batch.spi.BatchKey; @@ -23,7 +22,6 @@ import org.hibernate.engine.jdbc.mutation.group.PreparedStatementGroup; import org.hibernate.engine.jdbc.mutation.spi.BatchKeyAccess; import org.hibernate.engine.spi.SharedSessionContractImplementor; -import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.sql.model.MutationOperation; import org.hibernate.sql.model.MutationOperationGroup; import org.hibernate.sql.model.PreparableMutationOperation; @@ -79,12 +77,10 @@ public MutationExecutorStandard( List nonBatchedJdbcMutations = null; List selfExecutingMutations = null; - final List operations = mutationOperationGroup.getOperations(); - boolean hasAnyNonBatchedJdbcOperations = false; - for ( int i = operations.size() - 1; i >= 0; i-- ) { - final MutationOperation operation = operations.get( i ); + for ( int i = mutationOperationGroup.getNumberOfOperations() - 1; i >= 0; i-- ) { + final MutationOperation operation = mutationOperationGroup.getOperation( i ); if ( operation instanceof SelfExecutingUpdateOperation ) { final SelfExecutingUpdateOperation selfExecutingMutation = (SelfExecutingUpdateOperation) operation; if ( selfExecutingMutations == null ) { 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 0a0bba1192c0..2226e73911eb 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 d1f93ac6a2bf..1acf7cbb8531 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 @@ -27,6 +27,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 76067cc00055..b3268a09d297 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; @@ -228,7 +228,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 1140cb0e93f3..8758acabe958 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; @@ -34,7 +35,7 @@ public class DeleteRowsCoordinatorStandard implements DeleteRowsCoordinator { private final BasicBatchKey batchKey; private final MutationExecutorService mutationExecutorService; - private MutationOperationGroupSingle operationGroup; + private MutationOperationGroup operationGroup; public DeleteRowsCoordinatorStandard( CollectionMutationTarget mutationTarget, @@ -113,11 +114,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 40ee87db53b7..53e9e1b66d54 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; @@ -135,7 +134,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; @@ -153,16 +152,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 b83f567153af..f1e0e376d650 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; @@ -33,7 +34,7 @@ public class InsertRowsCoordinatorStandard implements InsertRowsCoordinator { private final BasicBatchKey batchKey; private final MutationExecutorService mutationExecutorService; - private MutationOperationGroupSingle operationGroup; + private MutationOperationGroup operationGroup; public InsertRowsCoordinatorStandard( CollectionMutationTarget mutationTarget, @@ -127,11 +128,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 372ef1e8c8d9..bf33c4ec0e78 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; @@ -42,7 +43,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 ); } @@ -153,7 +157,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; @@ -171,16 +175,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 6d5747eb5420..1573e66c19a4 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; @@ -31,7 +32,7 @@ public class RemoveCoordinatorStandard implements RemoveCoordinator { private final BasicBatchKey batchKey; private final MutationExecutorService mutationExecutorService; - private MutationOperationGroupSingle operationGroup; + private MutationOperationGroup operationGroup; /** * Creates the coordinator. @@ -67,7 +68,7 @@ public String getSqlString() { operationGroup = buildOperationGroup(); } - final JdbcMutationOperation operation = operationGroup.getSingleOperation(); + final JdbcMutationOperation operation = (JdbcMutationOperation) operationGroup.getSingleOperation(); return operation.getSqlString(); } @@ -117,7 +118,7 @@ public void deleteAllRows(Object key, SharedSessionContractImplementor session) } } - private MutationOperationGroupSingle buildOperationGroup() { + private MutationOperationGroup buildOperationGroup() { assert mutationTarget.getTargetPart() != null; assert mutationTarget.getTargetPart().getKeyDescriptor() != null; @@ -128,7 +129,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 063d3649b460..a2cccd47200c 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; @@ -30,7 +31,7 @@ public class RemoveCoordinatorTablePerSubclass implements RemoveCoordinator { private final OperationProducer operationProducer; private final MutationExecutorService mutationExecutorService; - private MutationOperationGroupSingle[] operationGroups; + private MutationOperationGroup[] operationGroups; /** * Creates the coordinator. @@ -72,7 +73,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(); @@ -80,7 +81,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, @@ -111,11 +112,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() ); @@ -123,7 +124,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; @@ -146,7 +147,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 1b6febe9ecc7..551410f821a2 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 9ff1d1ad5b37..e4cd2d6a9abb 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 e70ee2719bcc..ae075c55df8e 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/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index 0cae63929247..7b79e781c4ff 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 @@ -260,6 +260,7 @@ import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcParametersList; +import org.hibernate.sql.model.MutationOperation; import org.hibernate.sql.model.MutationOperationGroup; import org.hibernate.sql.model.ast.builder.MutationGroupBuilder; import org.hibernate.sql.results.graph.DomainResult; @@ -2908,25 +2909,41 @@ protected void logStaticSQL() { LOG.debugf( " Version select: %s", sqlVersionSelectString ); } - if ( insertCoordinator.getStaticInsertGroup() != null ) { - insertCoordinator.getStaticInsertGroup().forEachOperation( (tablePosition, mutation) -> { - if ( mutation instanceof JdbcOperation ) { - LOG.debugf( " Insert (%s): %s", tablePosition, ( (JdbcOperation) mutation ).getSqlString() ); + { + final MutationOperationGroup staticInsertGroup = insertCoordinator.getStaticInsertGroup(); + if ( staticInsertGroup != null ) { + for ( int i = 0; i < staticInsertGroup.getNumberOfOperations(); i++ ) { + final MutationOperation mutation = staticInsertGroup.getOperation( i ); + if ( mutation instanceof JdbcOperation ) { + LOG.debugf( " Insert (%s): %s", i, ( (JdbcOperation) mutation ).getSqlString() ); + } } - } ); + } } - updateCoordinator.getStaticUpdateGroup().forEachOperation( (tablePosition, mutation) -> { - if ( mutation instanceof JdbcOperation ) { - LOG.debugf( " Update (%s): %s", tablePosition, ( (JdbcOperation) mutation ).getSqlString() ); + { + final MutationOperationGroup staticUpdateGroup = updateCoordinator.getStaticUpdateGroup(); + if ( staticUpdateGroup != null ) { + for ( int i = 0; i < staticUpdateGroup.getNumberOfOperations(); i++ ) { + final MutationOperation mutation = staticUpdateGroup.getOperation( i ); + if ( mutation instanceof JdbcOperation ) { + LOG.debugf( " Update (%s): %s", i, ( (JdbcOperation) mutation ).getSqlString() ); + } + } } - } ); + } - deleteCoordinator.getStaticDeleteGroup().forEachOperation( (tablePosition, mutation) -> { - if ( mutation instanceof JdbcOperation ) { - LOG.debugf( " Delete (%s): %s", tablePosition, ( (JdbcOperation) mutation ).getSqlString() ); + { + final MutationOperationGroup staticDeleteGroup = deleteCoordinator.getStaticDeleteGroup(); + if ( staticDeleteGroup != null ) { + for ( int i = 0; i < staticDeleteGroup.getNumberOfOperations(); i++ ) { + final MutationOperation mutation = staticDeleteGroup.getOperation( i ); + if ( mutation instanceof JdbcOperation ) { + LOG.debugf( " Delete (%s): %s", i, ( (JdbcOperation) mutation ).getSqlString() ); + } + } } - } ); + } } } @@ -6052,12 +6069,14 @@ public String[] getSQLDeleteStrings() { } private String[] extractSqlStrings(MutationOperationGroup operationGroup) { - final String[] strings = new String[operationGroup.getNumberOfOperations()]; - operationGroup.forEachOperation( (tableIndex, mutation) -> { - if ( mutation instanceof JdbcOperation ) { - strings[tableIndex] = ( (JdbcOperation) mutation ).getSqlString(); + final int numberOfOperations = operationGroup.getNumberOfOperations(); + final String[] strings = new String[numberOfOperations]; + for ( int i = 0; i < numberOfOperations; i++ ) { + final MutationOperation operation = operationGroup.getOperation( i ); + if ( operation instanceof JdbcOperation ) { + strings[i] = ( (JdbcOperation) operation ).getSqlString(); } - } ); + } return strings; } 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 14581168b6ba..a8b3a9e87e34 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,13 +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 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 +80,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, 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/DeleteCoordinator.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/DeleteCoordinator.java index 3a6ed1d643df..f1a48ab96f6d 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/DeleteCoordinator.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/DeleteCoordinator.java @@ -23,6 +23,7 @@ import org.hibernate.metamodel.mapping.EntityVersionMapping; import org.hibernate.metamodel.mapping.SelectableMapping; import org.hibernate.persister.entity.AbstractEntityPersister; +import org.hibernate.sql.model.MutationOperation; import org.hibernate.sql.model.MutationOperationGroup; import org.hibernate.sql.model.MutationType; import org.hibernate.sql.model.ast.ColumnValueBinding; @@ -99,12 +100,13 @@ protected void doDynamicDelete( final MutationExecutor mutationExecutor = executor( session, operationGroup ); - operationGroup.forEachOperation( (position, mutation) -> { + for ( int i = 0; i < operationGroup.getNumberOfOperations(); i++ ) { + final MutationOperation mutation = operationGroup.getOperation( i ); if ( mutation != null ) { final String tableName = mutation.getTableDetails().getTableName(); mutationExecutor.getPreparedStatementDetails( tableName ); } - } ); + } applyLocking( null, loadedState, mutationExecutor, session ); @@ -215,10 +217,12 @@ protected void applyId( MutationExecutor mutationExecutor, MutationOperationGroup operationGroup, SharedSessionContractImplementor session) { + final JdbcValueBindings jdbcValueBindings = mutationExecutor.getJdbcValueBindings(); final EntityRowIdMapping rowIdMapping = entityPersister().getRowIdMapping(); - operationGroup.forEachOperation( (position, jdbcMutation) -> { + for ( int position = 0; position < operationGroup.getNumberOfOperations(); position++ ) { + final MutationOperation jdbcMutation = operationGroup.getOperation( position ); final EntityTableMapping tableDetails = (EntityTableMapping) jdbcMutation.getTableDetails(); breakDownIdJdbcValues( id, rowId, session, jdbcValueBindings, rowIdMapping, tableDetails ); final PreparedStatementDetails statementDetails = mutationExecutor.getPreparedStatementDetails( tableDetails.getTableName() ); @@ -227,7 +231,7 @@ protected void applyId( //noinspection resource statementDetails.resolveStatement(); } - } ); + } } private static void breakDownIdJdbcValues( @@ -281,11 +285,12 @@ protected void doStaticDelete( final MutationExecutor mutationExecutor = executor( session, operationGroupToUse ); - staticOperationGroup.forEachOperation( (position, mutation) -> { + for ( int position = 0; position < staticOperationGroup.getNumberOfOperations(); position++ ) { + final MutationOperation mutation = staticOperationGroup.getOperation( position ); if ( mutation != null ) { mutationExecutor.getPreparedStatementDetails( mutation.getTableDetails().getTableName() ); } - } ); + } if ( applyVersion ) { applyLocking( version, null, mutationExecutor, session ); 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 baa97dd5c0bd..1f139cf0acfa 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 @@ -28,6 +28,7 @@ import org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.persister.entity.AbstractEntityPersister; +import org.hibernate.sql.model.MutationOperation; import org.hibernate.sql.model.MutationOperationGroup; import org.hibernate.sql.model.MutationType; import org.hibernate.sql.model.TableMapping; @@ -113,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++ ) { @@ -122,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] ); } } } @@ -196,30 +198,33 @@ protected void decomposeForInsert( TableInclusionChecker tableInclusionChecker, SharedSessionContractImplementor session) { final JdbcValueBindings jdbcValueBindings = mutationExecutor.getJdbcValueBindings(); + final AttributeMappingsList attributeMappings = entityPersister().getAttributeMappings(); - mutationGroup.forEachOperation( (position, operation) -> { + for ( int position = 0; position < mutationGroup.getNumberOfOperations(); position++ ) { + final MutationOperation operation = mutationGroup.getOperation( position ); final EntityTableMapping tableDetails = (EntityTableMapping) operation.getTableDetails(); if ( tableInclusionChecker.include( tableDetails ) ) { final int[] attributeIndexes = tableDetails.getAttributeIndexes(); for ( int i = 0; i < attributeIndexes.length; i++ ) { final int attributeIndex = attributeIndexes[ i ]; if ( propertyInclusions[attributeIndex] ) { - final AttributeMapping mapping = entityPersister().getAttributeMappings().get( attributeIndex ); + final AttributeMapping mapping = attributeMappings.get( attributeIndex ); decomposeAttribute( values[attributeIndex], session, jdbcValueBindings, mapping ); } } } - } ); + } - mutationGroup.forEachOperation( (position, jdbcOperation) -> { - 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 ); } - } ); + } } protected void breakDownJdbcValue( 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 75c6475f810e..7c6be40137d0 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 c476f81a64d2..b42ee2b5a286 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; @@ -51,7 +52,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; @@ -800,7 +800,8 @@ protected void decomposeForUpdate( final JdbcValueBindings jdbcValueBindings = mutationExecutor.getJdbcValueBindings(); // apply values - jdbcOperationGroup.forEachOperation( (position, operation) -> { + for ( int position = 0; position < jdbcOperationGroup.getNumberOfOperations(); position++ ) { + final MutationOperation operation = jdbcOperationGroup.getOperation( position ); final EntityTableMapping tableMapping = (EntityTableMapping) operation.getTableDetails(); if ( valuesAnalysis.tablesNeedingUpdate.contains( tableMapping ) ) { final int[] attributeIndexes = tableMapping.getAttributeIndexes(); @@ -816,13 +817,14 @@ protected void decomposeForUpdate( ); } } - } ); + } // apply keys - jdbcOperationGroup.forEachOperation( (position, operation) -> { + for ( int position = 0; position < jdbcOperationGroup.getNumberOfOperations(); position++ ) { + final MutationOperation operation = jdbcOperationGroup.getOperation( position ); final EntityTableMapping tableMapping = (EntityTableMapping) operation.getTableDetails(); breakDownKeyJdbcValues( id, rowId, session, jdbcValueBindings, tableMapping ); - } ); + } } private void decomposeAttributeForUpdate( @@ -1680,7 +1682,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 62b85bbec2af..215d850f32b9 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,10 +6,11 @@ */ package org.hibernate.sql.model; -import java.util.List; import java.util.function.BiConsumer; import java.util.function.BiFunction; +import org.hibernate.engine.jdbc.mutation.internal.EntityMutationOperationGroup; + /** * Group of {@link MutationOperation} references for a specific * logical operation (target + type) @@ -17,6 +18,7 @@ * @author Steve Ebersole */ public interface MutationOperationGroup { + /** * The type of mutation (at the model-level) represented by this group. */ @@ -25,7 +27,7 @@ public interface MutationOperationGroup { /** * The model-part being mutated */ - MutationTarget getMutationTarget(); + MutationTarget getMutationTarget(); /** * Number of operations in this group @@ -37,22 +39,50 @@ public interface MutationOperationGroup { * * Throws an exception if there are more than one. */ - O getSingleOperation(); + MutationOperation getSingleOperation(); - List getOperations(); + /** + * Gets a specific MutationOperation from the group + * @param idx the index, starting from zero. + * @return + */ + MutationOperation getOperation(int idx); /** * Get the operation for a specific table. */ - O getOperation(String tableName); + MutationOperation getOperation(String tableName); /** - * Visit each operation + * Attempt to cast to the frequently uses subtype EntityMutationOperationGroup; + * returns null if this is not possible. + * @return */ - void forEachOperation(BiConsumer action); + default EntityMutationOperationGroup asEntityMutationOperationGroup() { + return null; + } /** - * Test whether any operations match the condition + * @deprecated Will be removed. Use the other methods to visit each operation. */ - boolean hasMatching(BiFunction matcher); + @Deprecated(forRemoval = true) + default void forEachOperation(BiConsumer action) { + for ( int i = 0; i < getNumberOfOperations(); i++ ) { + action.accept( i, (O) getOperation( i ) ); + } + } + + /** + * @deprecated Will be removed. Use the other methods to visit each operation. + */ + @Deprecated(forRemoval = true) + default boolean hasMatching(BiFunction matcher) { + for ( int i = 0; i < getNumberOfOperations(); i++ ) { + if ( matcher.apply( i, (O) getOperation( i ) ) ) { + return true; + } + } + return false; + } + } 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 320b81c7d7b1..5f56d31868a9 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 @@ -25,9 +25,13 @@ public interface MutationGroup { int getNumberOfTableMutations(); - > M getSingleTableMutation(); + TableMutation getSingleTableMutation(); + @Deprecated(forRemoval = true) > M getTableMutation(String tableName); + @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 aabd7628ae2a..000000000000 --- 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 000000000000..b2b7cde122e6 --- /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 f8f14c45076a..13d4b699a5af 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 @@ -46,12 +46,12 @@ public int getNumberOfTableMutations() { } @Override - public > M getSingleTableMutation() { + public TableMutation getSingleTableMutation() { return null; } @Override - public > M getTableMutation(String tableName) { + public TableMutation getTableMutation(String tableName) { return null; } @@ -59,6 +59,11 @@ public > M getTableMutat public > void forEachTableMutation(BiConsumer action) { } + @Override + public TableMutation getTableMutation(int i) { + return null; + } + @Override public String toString() { return String.format( 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 3c2adda364a0..c55c039ee499 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 @@ -51,16 +51,14 @@ public int getNumberOfTableMutations() { } @Override - public > M getSingleTableMutation() { - //noinspection unchecked - return (M) tableMutation; + public TableMutation getSingleTableMutation() { + return tableMutation; } @Override - public > M getTableMutation(String tableName) { + public TableMutation getTableMutation(String tableName) { assert tableMutation.getMutatingTable().getTableName().equals( tableName ); - //noinspection unchecked - return (M) tableMutation; + return tableMutation; } @Override @@ -69,6 +67,11 @@ public > void forEachTab action.accept( 0, (M) tableMutation ); } + @Override + public TableMutation getTableMutation(int i) { + return tableMutation; + } + @Override public String toString() { return String.format( 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 281b7cf2db0b..9d82b5e7fea6 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 @@ -50,18 +50,17 @@ public int getNumberOfTableMutations() { } @Override - public > M getSingleTableMutation() { + public TableMutation getSingleTableMutation() { throw new IllegalStateException( "Group contains multiple table mutations : " + mutationTarget.getNavigableRole() ); } @Override - public > M getTableMutation(String tableName) { + public TableMutation getTableMutation(String tableName) { for ( int i = 0; i < tableMutationList.size(); i++ ) { final TableMutation tableMutation = tableMutationList.get( i ); if ( tableMutation != null ) { if ( tableMutation.getMutatingTable().getTableName().equals( tableName ) ) { - //noinspection unchecked - return (M) tableMutation; + return tableMutation; } } } @@ -75,4 +74,10 @@ public > void forEachTab 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 000000000000..1d7da2cf41de --- /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 9c5df52f5fc4..000000000000 --- a/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationOperationGroupNone.java +++ /dev/null @@ -1,60 +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 java.util.Collections; -import java.util.List; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; - -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 O getSingleOperation() { - return null; - } - - @Override - public List getOperations() { - return Collections.emptyList(); - } - - @Override - public O getOperation(String tableName) { - return null; - } - - @Override - public void forEachOperation(BiConsumer action) { - } - - @Override - public boolean hasMatching(BiFunction matcher) { - return false; - } -} 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 e27bfe775ede..000000000000 --- a/hibernate-core/src/main/java/org/hibernate/sql/model/internal/MutationOperationGroupSingle.java +++ /dev/null @@ -1,78 +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 java.util.Collections; -import java.util.List; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; - -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 static org.hibernate.sql.model.ModelMutationLogging.MODEL_MUTATION_LOGGER; - -/** - * @author Steve Ebersole - */ -public class MutationOperationGroupSingle extends AbstractMutationOperationGroup { - private final MutationOperation operation; - - public MutationOperationGroupSingle(MutationType mutationType, MutationTarget mutationTarget, MutationOperation operation) { - super( mutationType, mutationTarget ); - this.operation = operation; - } - - public MutationOperationGroupSingle(MutationGroup mutationGroup, MutationOperation operation) { - this( mutationGroup.getMutationType(), mutationGroup.getMutationTarget(), operation ); - } - - @Override - public int getNumberOfOperations() { - return 1; - } - - @Override - public O getSingleOperation() { - //noinspection unchecked - return (O) operation; - } - - @Override - public List getOperations() { - //noinspection unchecked - return Collections.singletonList( (O) operation ); - } - - @Override - public O getOperation(String tableName) { - if ( !tableName.equals( operation.getTableDetails().getTableName() ) ) { - MODEL_MUTATION_LOGGER.debugf( - "Unexpected table name mismatch : `%s` - `%s`", - tableName, - operation.getTableDetails().getTableName() - ); - } - - //noinspection unchecked - return (O) operation; - } - - @Override - public void forEachOperation(BiConsumer action) { - //noinspection unchecked - action.accept( 0, (O) operation ); - } - - @Override - public boolean hasMatching(BiFunction matcher) { - //noinspection unchecked - return matcher.apply( 0, (O) 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 29cb70f1b6b0..1b8d455ca848 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,82 +6,105 @@ */ package org.hibernate.sql.model.internal; -import java.util.List; import java.util.Locale; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; 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 int getNumberOfOperations() { - return operations.size(); + public MutationType getMutationType() { + return mutationType; } @Override - public O getSingleOperation() { - if ( operations.size() == 1 ) { - //noinspection unchecked - return (O) operations.get( 0 ); - } - throw new IllegalStateException( - String.format( - Locale.ROOT, - "Group contains multiple table mutations - %s : %s ", - getMutationType().name(), - getMutationTarget().getNavigableRole() - ) - ); + public MutationTarget getMutationTarget() { + return mutationTarget; } - @SuppressWarnings("unchecked") @Override - public List getOperations() { - //noinspection rawtypes - return (List) operations; + public int getNumberOfOperations() { + return operations.length; } - @SuppressWarnings("unchecked") @Override - public O getOperation(String tableName) { - for ( int i = 0; i < operations.size(); i++ ) { - final MutationOperation operation = operations.get( i ); - if ( operation.getTableDetails().getTableName().equals( tableName ) ) { - return (O) operation; - } + 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() + ) + ); } - return null; } - @SuppressWarnings("unchecked") @Override - public void forEachOperation(BiConsumer action) { - for ( int i = 0; i < operations.size(); i++ ) { - action.accept( i, (O) operations.get( i ) ); - } + public MutationOperation getOperation(int idx) { + return operations[idx]; } - @SuppressWarnings("unchecked") @Override - public boolean hasMatching(BiFunction matcher) { - for ( int i = 0; i < operations.size(); i++ ) { - if ( matcher.apply( i, (O) operations.get( i ) ) ) { - return true; + 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 false; + return null; } + } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/boot/database/qualfiedTableNaming/DefaultCatalogAndSchemaTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/boot/database/qualfiedTableNaming/DefaultCatalogAndSchemaTest.java index a7c784506988..4774bdc90069 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/boot/database/qualfiedTableNaming/DefaultCatalogAndSchemaTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/boot/database/qualfiedTableNaming/DefaultCatalogAndSchemaTest.java @@ -47,6 +47,7 @@ import org.hibernate.query.sqm.mutation.internal.temptable.LocalTemporaryTableStrategy; import org.hibernate.query.sqm.mutation.internal.temptable.PersistentTableStrategy; import org.hibernate.service.spi.ServiceRegistryImplementor; +import org.hibernate.sql.model.MutationOperation; import org.hibernate.sql.model.MutationOperationGroup; import org.hibernate.sql.model.PreparableMutationOperation; import org.hibernate.tool.hbm2ddl.SchemaExport; @@ -408,38 +409,51 @@ private void verifyEntityPersisterQualifiers(Class entityClass, ExpectedQuali // This will include SQL generated by ID generators in some cases, which will be validated here // because ID generators table/sequence names are prefixed with the owning entity name. - final MutationOperationGroup staticSqlInsertGroup = persister.getInsertCoordinator().getStaticInsertGroup(); - final String[] insertSqls = new String[ staticSqlInsertGroup.getNumberOfOperations()]; - staticSqlInsertGroup.forEachOperation( (tablePosition, insertOperation) -> { - if ( insertOperation instanceof PreparableMutationOperation ) { - insertSqls[tablePosition] = ( (PreparableMutationOperation) insertOperation ).getSqlString(); + { + final MutationOperationGroup staticSqlInsertGroup = persister.getInsertCoordinator().getStaticInsertGroup(); + final String[] insertSqls = new String[staticSqlInsertGroup.getNumberOfOperations()]; + for ( int tablePosition = 0; + tablePosition < staticSqlInsertGroup.getNumberOfOperations(); + tablePosition++ ) { + final MutationOperation insertOperation = staticSqlInsertGroup.getOperation( tablePosition ); + if ( insertOperation instanceof PreparableMutationOperation ) { + insertSqls[tablePosition] = ( (PreparableMutationOperation) insertOperation ).getSqlString(); + } } - } ); - - verifyOnlyQualifier( insertSqls, SqlType.RUNTIME, jpaEntityName, expectedQualifier ); + verifyOnlyQualifier( insertSqls, SqlType.RUNTIME, jpaEntityName, expectedQualifier ); + } String identitySelectString = persister.getIdentitySelectString(); if ( identitySelectString != null ) { verifyOnlyQualifierOptional( identitySelectString, SqlType.RUNTIME, jpaEntityName, expectedQualifier ); } - final MutationOperationGroup staticSqlUpdateGroup = persister.getUpdateCoordinator().getStaticUpdateGroup(); - final String[] sqlUpdateStrings = new String[staticSqlUpdateGroup.getNumberOfOperations()]; - staticSqlUpdateGroup.forEachOperation( (tablePosition, operation) -> { - if ( operation instanceof PreparableMutationOperation ) { - sqlUpdateStrings[tablePosition] = ( (PreparableMutationOperation) operation ).getSqlString(); + { + final MutationOperationGroup staticSqlUpdateGroup = persister.getUpdateCoordinator().getStaticUpdateGroup(); + final String[] sqlUpdateStrings = new String[staticSqlUpdateGroup.getNumberOfOperations()]; + for ( int tablePosition = 0; + tablePosition < staticSqlUpdateGroup.getNumberOfOperations(); + tablePosition++ ) { + final MutationOperation operation = staticSqlUpdateGroup.getOperation( tablePosition ); + if ( operation instanceof PreparableMutationOperation ) { + sqlUpdateStrings[tablePosition] = ( (PreparableMutationOperation) operation ).getSqlString(); + } } - } ); - verifyOnlyQualifier( sqlUpdateStrings, SqlType.RUNTIME, jpaEntityName, expectedQualifier ); - - final MutationOperationGroup staticDeleteGroup = persister.getDeleteCoordinator().getStaticDeleteGroup(); - final String[] sqlDeleteStrings = new String[staticDeleteGroup.getNumberOfOperations()]; - staticDeleteGroup.forEachOperation( (tablePosition, operation) -> { - if ( operation instanceof PreparableMutationOperation ) { - sqlDeleteStrings[tablePosition] = ( (PreparableMutationOperation) operation ).getSqlString(); + verifyOnlyQualifier( sqlUpdateStrings, SqlType.RUNTIME, jpaEntityName, expectedQualifier ); + } + + + { + final MutationOperationGroup staticDeleteGroup = persister.getDeleteCoordinator().getStaticDeleteGroup(); + final String[] sqlDeleteStrings = new String[staticDeleteGroup.getNumberOfOperations()]; + for ( int tablePosition = 0; tablePosition < staticDeleteGroup.getNumberOfOperations(); tablePosition++ ) { + final MutationOperation operation = staticDeleteGroup.getOperation( tablePosition ); + if ( operation instanceof PreparableMutationOperation ) { + sqlDeleteStrings[tablePosition] = ( (PreparableMutationOperation) operation ).getSqlString(); + } } - } ); - verifyOnlyQualifier( sqlDeleteStrings, SqlType.RUNTIME, jpaEntityName, expectedQualifier ); + verifyOnlyQualifier( sqlDeleteStrings, SqlType.RUNTIME, jpaEntityName, expectedQualifier ); + } // This is used in the "select" id generator in particular. verifyOnlyQualifierOptional( persister.getSelectByUniqueKeyString( "basic" ), SqlType.RUNTIME,