HHH-15393 - Improve write-paths to use mapping model
This commit is contained in:
parent
7461100c39
commit
94e2b599e4
|
@ -8,14 +8,9 @@ package org.hibernate.engine.jdbc.mutation.internal;
|
|||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
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;
|
||||
import org.hibernate.engine.jdbc.mutation.JdbcValueBindings;
|
||||
import org.hibernate.engine.jdbc.mutation.MutationExecutor;
|
||||
import org.hibernate.engine.jdbc.mutation.OperationResultChecker;
|
||||
|
@ -59,26 +54,14 @@ public class MutationExecutorPostInsert implements MutationExecutor {
|
|||
|
||||
private final PreparedStatementDetails identityInsertStatementDetails;
|
||||
|
||||
/**
|
||||
* The batched statements
|
||||
*/
|
||||
private final Batch batch;
|
||||
|
||||
/**
|
||||
* Any non-batched JDBC statements
|
||||
*/
|
||||
private final PreparedStatementGroup nonBatchedStatementGroup;
|
||||
private final PreparedStatementGroup secondaryTablesStatementGroup;
|
||||
|
||||
private final JdbcValueBindingsImpl valueBindings;
|
||||
|
||||
private enum StatementLocation { IDENTITY, BATCHED, NON_BATCHED }
|
||||
private final Map<String, StatementLocation> statementLocationMap = new HashMap<>();
|
||||
|
||||
public MutationExecutorPostInsert(
|
||||
MutationOperationGroup mutationOperationGroup,
|
||||
Supplier<BatchKey> batchKeySupplier,
|
||||
int batchSize,
|
||||
SharedSessionContractImplementor session) {
|
||||
public MutationExecutorPostInsert(MutationOperationGroup mutationOperationGroup, SharedSessionContractImplementor session) {
|
||||
this.mutationTarget = (EntityMutationTarget) mutationOperationGroup.getMutationTarget();
|
||||
this.valueBindings = new JdbcValueBindingsImpl(
|
||||
MutationType.INSERT,
|
||||
|
@ -92,12 +75,8 @@ public class MutationExecutorPostInsert implements MutationExecutor {
|
|||
identityInsertOperation,
|
||||
session
|
||||
);
|
||||
statementLocationMap.put( mutationTarget.getIdentifierTableName(), StatementLocation.IDENTITY );
|
||||
|
||||
final BatchKey batchKey = batchKeySupplier.get();
|
||||
|
||||
List<PreparableMutationOperation> batchedJdbcMutations = null;
|
||||
List<PreparableMutationOperation> nonBatchedJdbcMutations = null;
|
||||
List<PreparableMutationOperation> secondaryTableMutations = null;
|
||||
|
||||
final List<MutationOperation> operations = mutationOperationGroup.getOperations();
|
||||
for ( int i = 0; i < operations.size(); i++ ) {
|
||||
|
@ -112,48 +91,17 @@ public class MutationExecutorPostInsert implements MutationExecutor {
|
|||
assert ! (operation instanceof SelfExecutingUpdateOperation );
|
||||
|
||||
final PreparableMutationOperation preparableMutationOperation = (PreparableMutationOperation) operation;
|
||||
if ( preparableMutationOperation.canBeBatched( batchKey, batchSize ) ) {
|
||||
if ( batchedJdbcMutations == null ) {
|
||||
batchedJdbcMutations = new ArrayList<>();
|
||||
}
|
||||
batchedJdbcMutations.add( preparableMutationOperation );
|
||||
statementLocationMap.put( operation.getTableDetails().getTableName(), StatementLocation.BATCHED );
|
||||
}
|
||||
else {
|
||||
if ( nonBatchedJdbcMutations == null ) {
|
||||
nonBatchedJdbcMutations = new ArrayList<>();
|
||||
}
|
||||
nonBatchedJdbcMutations.add( preparableMutationOperation );
|
||||
statementLocationMap.put( operation.getTableDetails().getTableName(), StatementLocation.NON_BATCHED );
|
||||
if ( secondaryTableMutations == null ) {
|
||||
secondaryTableMutations = new ArrayList<>();
|
||||
}
|
||||
secondaryTableMutations.add( preparableMutationOperation );
|
||||
}
|
||||
|
||||
// todo (mutation) : consider creating single PreparedStatementGroup for all
|
||||
// batched and non-batched statements. we then need a way to know whether a
|
||||
// statement is batched or not. `PreparedStatementDetails#isBatched`?
|
||||
|
||||
if ( batchedJdbcMutations == null || batchedJdbcMutations.isEmpty() ) {
|
||||
this.batch = null;
|
||||
}
|
||||
else {
|
||||
final List<PreparableMutationOperation> batchedMutationsRef = batchedJdbcMutations;
|
||||
this.batch = session.getJdbcCoordinator().getBatch2(
|
||||
batchKey,
|
||||
batchSize,
|
||||
() -> ModelMutationHelper.toPreparedStatementGroup(
|
||||
this.secondaryTablesStatementGroup = ModelMutationHelper.toPreparedStatementGroup(
|
||||
MutationType.INSERT,
|
||||
mutationTarget,
|
||||
batchedMutationsRef,
|
||||
session
|
||||
)
|
||||
);
|
||||
assert batch != null;
|
||||
}
|
||||
|
||||
this.nonBatchedStatementGroup = ModelMutationHelper.toPreparedStatementGroup(
|
||||
MutationType.INSERT,
|
||||
mutationTarget,
|
||||
nonBatchedJdbcMutations,
|
||||
secondaryTableMutations,
|
||||
session
|
||||
);
|
||||
}
|
||||
|
@ -174,27 +122,11 @@ public class MutationExecutorPostInsert implements MutationExecutor {
|
|||
|
||||
@Override
|
||||
public PreparedStatementDetails getPreparedStatementDetails(String tableName) {
|
||||
final StatementLocation statementLocation = statementLocationMap.get( tableName );
|
||||
if ( statementLocation == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( statementLocation == StatementLocation.IDENTITY ) {
|
||||
assert mutationTarget.getIdentifierTableName().equals( tableName );
|
||||
if ( mutationTarget.getIdentifierTableName().equals( tableName ) ) {
|
||||
return identityInsertStatementDetails;
|
||||
}
|
||||
|
||||
if ( statementLocation == StatementLocation.BATCHED ) {
|
||||
assert batch != null;
|
||||
return batch.getStatementGroup().getPreparedStatementDetails( tableName );
|
||||
}
|
||||
|
||||
if ( statementLocation == StatementLocation.NON_BATCHED ) {
|
||||
assert nonBatchedStatementGroup != null;
|
||||
return nonBatchedStatementGroup.getPreparedStatementDetails( tableName );
|
||||
}
|
||||
|
||||
return null;
|
||||
return secondaryTablesStatementGroup.getPreparedStatementDetails( tableName );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -215,19 +147,8 @@ public class MutationExecutorPostInsert implements MutationExecutor {
|
|||
);
|
||||
}
|
||||
|
||||
if ( nonBatchedStatementGroup != null ) {
|
||||
nonBatchedStatementGroup.forEachStatement( (tableName, statementDetails) -> executeWithId(
|
||||
id,
|
||||
tableName,
|
||||
statementDetails,
|
||||
inclusionChecker,
|
||||
resultChecker,
|
||||
session
|
||||
) );
|
||||
}
|
||||
|
||||
if ( batch != null ) {
|
||||
batch.getStatementGroup().forEachStatement( (tableName, statementDetails) -> executeWithId(
|
||||
if ( secondaryTablesStatementGroup != null ) {
|
||||
secondaryTablesStatementGroup.forEachStatement( (tableName, statementDetails) -> executeWithId(
|
||||
id,
|
||||
tableName,
|
||||
statementDetails,
|
||||
|
@ -301,7 +222,7 @@ public class MutationExecutorPostInsert implements MutationExecutor {
|
|||
|
||||
@Override
|
||||
public void release() {
|
||||
nonBatchedStatementGroup.release();
|
||||
secondaryTablesStatementGroup.release();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -69,6 +69,6 @@ public class MutationExecutorServiceInitiator implements StandardServiceInitiato
|
|||
}
|
||||
|
||||
private MutationExecutorService createStandardService(Map<String, Object> configurationValues, ServiceRegistryImplementor registry) {
|
||||
return new StandardMutationExecutorService( configurationValues, registry );
|
||||
return new StandardMutationExecutorService( configurationValues );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -188,7 +188,6 @@ public class MutationExecutorStandard extends AbstractMutationExecutor {
|
|||
@Override
|
||||
public void release() {
|
||||
nonBatchedStatementGroup.release();
|
||||
// todo (mutation) :implement
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -51,12 +51,6 @@ public class PreparedStatementDetailsStandard implements PreparedStatementDetail
|
|||
Supplier<PreparedStatement> jdbcStatementCreator,
|
||||
Expectation expectation,
|
||||
JdbcServices jdbcServices) {
|
||||
|
||||
// todo (mutation) : have `parameterDescriptors` be passed in.
|
||||
// - these descriptors being only available relative solely
|
||||
// to a preparable operation, rather than more widely scoped to
|
||||
// the `MutationOperation`, causes problems for self-executing operations
|
||||
|
||||
this.mutatingTableDetails = tableMutation.getTableDetails();
|
||||
this.sql = sql;
|
||||
this.jdbcStatementCreator = jdbcStatementCreator;
|
||||
|
|
|
@ -17,7 +17,6 @@ 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.service.spi.ServiceRegistryImplementor;
|
||||
import org.hibernate.sql.model.MutationOperation;
|
||||
import org.hibernate.sql.model.MutationOperationGroup;
|
||||
import org.hibernate.sql.model.MutationTarget;
|
||||
|
@ -35,7 +34,7 @@ import org.hibernate.sql.model.SelfExecutingUpdateOperation;
|
|||
public class StandardMutationExecutorService implements MutationExecutorService {
|
||||
private final int globalBatchSize;
|
||||
|
||||
public StandardMutationExecutorService(Map<String, Object> configurationValues, ServiceRegistryImplementor registry) {
|
||||
public StandardMutationExecutorService(Map<String, Object> configurationValues) {
|
||||
this( ConfigurationHelper.getInt( Environment.STATEMENT_BATCH_SIZE, configurationValues, 1 ) );
|
||||
}
|
||||
|
||||
|
@ -66,7 +65,7 @@ public class StandardMutationExecutorService implements MutationExecutorService
|
|||
assert mutationTarget instanceof EntityMappingType;
|
||||
|
||||
if ( numberOfOperations > 1 ) {
|
||||
return new MutationExecutorPostInsert( operationGroup, batchKeySupplier, batchSizeToUse, session );
|
||||
return new MutationExecutorPostInsert( operationGroup, session );
|
||||
}
|
||||
|
||||
return new MutationExecutorPostInsertSingleTable( operationGroup, session );
|
||||
|
|
|
@ -11,4 +11,7 @@
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Incubating
|
||||
package org.hibernate.engine.jdbc.mutation;
|
||||
|
||||
import org.hibernate.Incubating;
|
||||
|
|
|
@ -7,12 +7,15 @@
|
|||
|
||||
/**
|
||||
* Defines support for performing mutation operations against collections.
|
||||
* <p/>
|
||||
* The names used here are logical. E.g. "inserting a row" may actually
|
||||
*
|
||||
* @apiNote The names used here are logical. E.g. "inserting a row" may actually
|
||||
* execute an UPDATE statement instead of an INSERT. This is generally
|
||||
* delineated based on whether there is a collection table involved or
|
||||
* not. In standard Hibernate terms, this breaks down to the distinction
|
||||
* between {@link org.hibernate.persister.collection.BasicCollectionPersister}
|
||||
* and {@link org.hibernate.persister.collection.OneToManyPersister}.
|
||||
*/
|
||||
@Incubating
|
||||
package org.hibernate.persister.collection.mutation;
|
||||
|
||||
import org.hibernate.Incubating;
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Defines support for performing mutation operations originating
|
||||
* from persistence-context events
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Incubating
|
||||
package org.hibernate.persister.entity.mutation;
|
||||
|
||||
import org.hibernate.Incubating;
|
|
@ -77,7 +77,11 @@ public interface MutationOperation {
|
|||
TableMapping getTableDetails();
|
||||
|
||||
/**
|
||||
* Find the JDBC parameter to be used for the specified column
|
||||
* Find the JDBC parameter to be used for the specified column.
|
||||
*
|
||||
* @return The descriptor, or null if none match.
|
||||
*
|
||||
* @see #getJdbcValueDescriptor
|
||||
*/
|
||||
JdbcValueDescriptor findValueDescriptor(String columnName, ParameterUsage usage);
|
||||
|
||||
|
|
Loading…
Reference in New Issue