HHH-16390 - Execution of non-batched statements do not force execution of current batch
HHH-16319 - test
This commit is contained in:
parent
a9f51a3eae
commit
be10b32b94
|
@ -18,6 +18,7 @@ import java.util.function.Supplier;
|
||||||
import org.hibernate.ConnectionReleaseMode;
|
import org.hibernate.ConnectionReleaseMode;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.TransactionException;
|
import org.hibernate.TransactionException;
|
||||||
|
import org.hibernate.engine.jdbc.batch.JdbcBatchLogging;
|
||||||
import org.hibernate.engine.jdbc.batch.spi.Batch;
|
import org.hibernate.engine.jdbc.batch.spi.Batch;
|
||||||
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
|
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
|
||||||
import org.hibernate.engine.jdbc.mutation.group.PreparedStatementGroup;
|
import org.hibernate.engine.jdbc.mutation.group.PreparedStatementGroup;
|
||||||
|
@ -192,6 +193,18 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void conditionallyExecuteBatch(BatchKey key) {
|
||||||
|
if ( currentBatch == null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !currentBatch.getKey().equals( key ) ) {
|
||||||
|
JdbcBatchLogging.BATCH_LOGGER.debugf( "Conditionally executing batch - %s", currentBatch.getKey() );
|
||||||
|
currentBatch.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void abortBatch() {
|
public void abortBatch() {
|
||||||
if ( currentBatch != null ) {
|
if ( currentBatch != null ) {
|
||||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.engine.jdbc.mutation.internal;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
|
||||||
import org.hibernate.engine.jdbc.mutation.JdbcValueBindings;
|
import org.hibernate.engine.jdbc.mutation.JdbcValueBindings;
|
||||||
import org.hibernate.engine.jdbc.mutation.MutationExecutor;
|
import org.hibernate.engine.jdbc.mutation.MutationExecutor;
|
||||||
import org.hibernate.engine.jdbc.mutation.OperationResultChecker;
|
import org.hibernate.engine.jdbc.mutation.OperationResultChecker;
|
||||||
|
@ -26,6 +27,15 @@ import static org.hibernate.sql.model.ModelMutationLogging.MODEL_MUTATION_LOGGER
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractMutationExecutor implements MutationExecutor {
|
public abstract class AbstractMutationExecutor implements MutationExecutor {
|
||||||
|
/**
|
||||||
|
* Executors with non-batched operations should call this to clean up any "previous" batch
|
||||||
|
* before starting their work
|
||||||
|
*/
|
||||||
|
protected void prepareForNonBatchedWork(BatchKey batchKey, SharedSessionContractImplementor session) {
|
||||||
|
// if there is a current batch, make sure to execute it first
|
||||||
|
session.getJdbcCoordinator().conditionallyExecuteBatch( batchKey );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Templated implementation of execution as <ol>
|
* Templated implementation of execution as <ol>
|
||||||
* <li>{@link #performNonBatchedOperations}</li>
|
* <li>{@link #performNonBatchedOperations}</li>
|
||||||
|
|
|
@ -22,8 +22,8 @@ public class MutationExecutorSingleNonBatched extends AbstractSingleMutationExec
|
||||||
PreparableMutationOperation mutationOperation,
|
PreparableMutationOperation mutationOperation,
|
||||||
SharedSessionContractImplementor session) {
|
SharedSessionContractImplementor session) {
|
||||||
super( mutationOperation, session );
|
super( mutationOperation, session );
|
||||||
|
|
||||||
this.statementGroup = new PreparedStatementGroupSingleTable( mutationOperation, session );
|
this.statementGroup = new PreparedStatementGroupSingleTable( mutationOperation, session );
|
||||||
|
prepareForNonBatchedWork( null, session );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -33,6 +33,8 @@ public class MutationExecutorSingleSelfExecuting extends AbstractMutationExecuto
|
||||||
this::findJdbcValueDescriptor,
|
this::findJdbcValueDescriptor,
|
||||||
session
|
session
|
||||||
);
|
);
|
||||||
|
|
||||||
|
prepareForNonBatchedWork( null, session );
|
||||||
}
|
}
|
||||||
|
|
||||||
private JdbcValueDescriptor findJdbcValueDescriptor(String tableName, String columnName, ParameterUsage usage) {
|
private JdbcValueDescriptor findJdbcValueDescriptor(String tableName, String columnName, ParameterUsage usage) {
|
||||||
|
|
|
@ -21,7 +21,9 @@ import org.hibernate.engine.jdbc.mutation.ParameterUsage;
|
||||||
import org.hibernate.engine.jdbc.mutation.TableInclusionChecker;
|
import org.hibernate.engine.jdbc.mutation.TableInclusionChecker;
|
||||||
import org.hibernate.engine.jdbc.mutation.group.PreparedStatementDetails;
|
import org.hibernate.engine.jdbc.mutation.group.PreparedStatementDetails;
|
||||||
import org.hibernate.engine.jdbc.mutation.group.PreparedStatementGroup;
|
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.engine.spi.SharedSessionContractImplementor;
|
||||||
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.sql.model.MutationOperation;
|
import org.hibernate.sql.model.MutationOperation;
|
||||||
import org.hibernate.sql.model.MutationOperationGroup;
|
import org.hibernate.sql.model.MutationOperationGroup;
|
||||||
import org.hibernate.sql.model.PreparableMutationOperation;
|
import org.hibernate.sql.model.PreparableMutationOperation;
|
||||||
|
@ -30,6 +32,8 @@ import org.hibernate.sql.model.TableMapping;
|
||||||
import org.hibernate.sql.model.ValuesAnalysis;
|
import org.hibernate.sql.model.ValuesAnalysis;
|
||||||
import org.hibernate.sql.model.jdbc.JdbcValueDescriptor;
|
import org.hibernate.sql.model.jdbc.JdbcValueDescriptor;
|
||||||
|
|
||||||
|
import static org.hibernate.internal.util.collections.CollectionHelper.isNotEmpty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard MutationExecutor implementation
|
* Standard MutationExecutor implementation
|
||||||
*
|
*
|
||||||
|
@ -60,12 +64,12 @@ public class MutationExecutorStandard extends AbstractMutationExecutor {
|
||||||
|
|
||||||
public MutationExecutorStandard(
|
public MutationExecutorStandard(
|
||||||
MutationOperationGroup mutationOperationGroup,
|
MutationOperationGroup mutationOperationGroup,
|
||||||
Supplier<BatchKey> batchKeySupplier,
|
BatchKeyAccess batchKeySupplier,
|
||||||
int batchSize,
|
int batchSize,
|
||||||
SharedSessionContractImplementor session) {
|
SharedSessionContractImplementor session) {
|
||||||
this.mutationOperationGroup = mutationOperationGroup;
|
this.mutationOperationGroup = mutationOperationGroup;
|
||||||
|
|
||||||
final BatchKey batchKey = batchKeySupplier.get();
|
final BatchKey batchKey = batchKeySupplier.getBatchKey();
|
||||||
|
|
||||||
// split the table operations into batchable and non-batchable -
|
// split the table operations into batchable and non-batchable -
|
||||||
// 1. batchable statements are handle via Batch
|
// 1. batchable statements are handle via Batch
|
||||||
|
@ -155,6 +159,10 @@ public class MutationExecutorStandard extends AbstractMutationExecutor {
|
||||||
this::findJdbcValueDescriptor,
|
this::findJdbcValueDescriptor,
|
||||||
session
|
session
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ( isNotEmpty( nonBatchedJdbcMutations ) || isNotEmpty( selfExecutingMutations ) ) {
|
||||||
|
prepareForNonBatchedWork( batchKey, session );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PreparedStatementGroup getNonBatchedStatementGroup() {
|
protected PreparedStatementGroup getNonBatchedStatementGroup() {
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* 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.engine.jdbc.batch.spi.BatchKey;
|
||||||
|
import org.hibernate.engine.jdbc.mutation.spi.BatchKeyAccess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A form of BatchKeyAccess for cases where batching is not wanted, which is
|
||||||
|
* signified by a BatchKey of {@code null}
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class NoBatchKeyAccess implements BatchKeyAccess {
|
||||||
|
/**
|
||||||
|
* Singleton access
|
||||||
|
*/
|
||||||
|
public static final NoBatchKeyAccess INSTANCE = new NoBatchKeyAccess();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BatchKey getBatchKey() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,7 @@ import java.util.function.Supplier;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
|
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
|
||||||
import org.hibernate.engine.jdbc.mutation.MutationExecutor;
|
import org.hibernate.engine.jdbc.mutation.MutationExecutor;
|
||||||
|
import org.hibernate.engine.jdbc.mutation.spi.BatchKeyAccess;
|
||||||
import org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService;
|
import org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
|
@ -44,7 +45,7 @@ public class StandardMutationExecutorService implements MutationExecutorService
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MutationExecutor createExecutor(
|
public MutationExecutor createExecutor(
|
||||||
Supplier<BatchKey> batchKeySupplier,
|
BatchKeyAccess batchKeySupplier,
|
||||||
MutationOperationGroup operationGroup,
|
MutationOperationGroup operationGroup,
|
||||||
SharedSessionContractImplementor session) {
|
SharedSessionContractImplementor session) {
|
||||||
// decide whether to use batching - any number > one means to batch
|
// decide whether to use batching - any number > one means to batch
|
||||||
|
@ -78,7 +79,7 @@ public class StandardMutationExecutorService implements MutationExecutorService
|
||||||
}
|
}
|
||||||
|
|
||||||
final PreparableMutationOperation jdbcOperation = (PreparableMutationOperation) singleOperation;
|
final PreparableMutationOperation jdbcOperation = (PreparableMutationOperation) singleOperation;
|
||||||
final BatchKey batchKey = batchKeySupplier.get();
|
final BatchKey batchKey = batchKeySupplier.getBatchKey();
|
||||||
if ( jdbcOperation.canBeBatched( batchKey, batchSizeToUse ) ) {
|
if ( jdbcOperation.canBeBatched( batchKey, batchSizeToUse ) ) {
|
||||||
return new MutationExecutorSingleBatched( jdbcOperation, batchKey, batchSizeToUse, session );
|
return new MutationExecutorSingleBatched( jdbcOperation, batchKey, batchSizeToUse, session );
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* 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.spi;
|
||||||
|
|
||||||
|
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides access to a BatchKey as part of creating an {@linkplain MutationExecutorService#createExecutor executor}.
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public interface BatchKeyAccess {
|
||||||
|
/**
|
||||||
|
* The BatchKey to use
|
||||||
|
*/
|
||||||
|
BatchKey getBatchKey();
|
||||||
|
}
|
|
@ -6,9 +6,6 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.engine.jdbc.mutation.spi;
|
package org.hibernate.engine.jdbc.mutation.spi;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
|
|
||||||
import org.hibernate.engine.jdbc.mutation.MutationExecutor;
|
import org.hibernate.engine.jdbc.mutation.MutationExecutor;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.service.Service;
|
import org.hibernate.service.Service;
|
||||||
|
@ -21,8 +18,11 @@ import org.hibernate.sql.model.MutationOperationGroup;
|
||||||
*/
|
*/
|
||||||
public interface MutationExecutorService extends Service {
|
public interface MutationExecutorService extends Service {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an executor for the given {@code operationGroup}, potentially using batching
|
||||||
|
*/
|
||||||
MutationExecutor createExecutor(
|
MutationExecutor createExecutor(
|
||||||
Supplier<BatchKey> batchKeySupplier,
|
BatchKeyAccess batchKeySupplier,
|
||||||
MutationOperationGroup operationGroup,
|
MutationOperationGroup operationGroup,
|
||||||
SharedSessionContractImplementor session);
|
SharedSessionContractImplementor session);
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,12 @@ public interface JdbcCoordinator extends Serializable, TransactionCoordinatorOwn
|
||||||
*/
|
*/
|
||||||
void executeBatch();
|
void executeBatch();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Conditionally execute the currently managed batch (if any), if the
|
||||||
|
* keys do not match
|
||||||
|
*/
|
||||||
|
void conditionallyExecuteBatch(BatchKey key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abort the currently managed batch (if any)
|
* Abort the currently managed batch (if any)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -10,8 +10,11 @@ import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.Internal;
|
import org.hibernate.Internal;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
|
||||||
import org.hibernate.engine.jdbc.mutation.JdbcValueBindings;
|
import org.hibernate.engine.jdbc.mutation.JdbcValueBindings;
|
||||||
import org.hibernate.engine.jdbc.mutation.ParameterUsage;
|
import org.hibernate.engine.jdbc.mutation.ParameterUsage;
|
||||||
|
import org.hibernate.engine.jdbc.mutation.internal.NoBatchKeyAccess;
|
||||||
|
import org.hibernate.engine.jdbc.mutation.spi.BatchKeyAccess;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.generator.OnExecutionGenerator;
|
import org.hibernate.generator.OnExecutionGenerator;
|
||||||
|
@ -60,6 +63,18 @@ public abstract class AbstractMutationCoordinator {
|
||||||
return factory().getJdbcServices().getDialect();
|
return factory().getJdbcServices().getDialect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected BatchKeyAccess resolveBatchKeyAccess(boolean dynamicUpdate, SharedSessionContractImplementor session) {
|
||||||
|
if ( !dynamicUpdate
|
||||||
|
&& session.getTransactionCoordinator() != null
|
||||||
|
&& session.getTransactionCoordinator().isTransactionActive() ) {
|
||||||
|
return this::getBatchKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NoBatchKeyAccess.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract BatchKey getBatchKey();
|
||||||
|
|
||||||
protected MutationOperationGroup createOperationGroup(ValuesAnalysis valuesAnalysis, MutationGroup mutationGroup) {
|
protected MutationOperationGroup createOperationGroup(ValuesAnalysis valuesAnalysis, MutationGroup mutationGroup) {
|
||||||
final int numberOfTableMutations = mutationGroup.getNumberOfTableMutations();
|
final int numberOfTableMutations = mutationGroup.getNumberOfTableMutations();
|
||||||
switch ( numberOfTableMutations ) {
|
switch ( numberOfTableMutations ) {
|
||||||
|
|
|
@ -133,9 +133,7 @@ public class DeleteCoordinator extends AbstractMutationCoordinator {
|
||||||
return session.getFactory()
|
return session.getFactory()
|
||||||
.getServiceRegistry()
|
.getServiceRegistry()
|
||||||
.getService( MutationExecutorService.class )
|
.getService( MutationExecutorService.class )
|
||||||
.createExecutor( ( session.getTransactionCoordinator() != null &&
|
.createExecutor( resolveBatchKeyAccess( false, session ), group, session );
|
||||||
session.getTransactionCoordinator().isTransactionActive() ? () -> batchKey : () -> null ),
|
|
||||||
group, session );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void applyLocking(
|
protected void applyLocking(
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.List;
|
||||||
import org.hibernate.Internal;
|
import org.hibernate.Internal;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey;
|
import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey;
|
||||||
|
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
|
||||||
import org.hibernate.engine.jdbc.mutation.JdbcValueBindings;
|
import org.hibernate.engine.jdbc.mutation.JdbcValueBindings;
|
||||||
import org.hibernate.engine.jdbc.mutation.MutationExecutor;
|
import org.hibernate.engine.jdbc.mutation.MutationExecutor;
|
||||||
import org.hibernate.engine.jdbc.mutation.ParameterUsage;
|
import org.hibernate.engine.jdbc.mutation.ParameterUsage;
|
||||||
|
@ -79,7 +80,8 @@ public class InsertCoordinator extends AbstractMutationCoordinator {
|
||||||
return staticInsertGroup;
|
return staticInsertGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BasicBatchKey getInsertBatchKey() {
|
@Override
|
||||||
|
protected BatchKey getBatchKey() {
|
||||||
return batchKey;
|
return batchKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,9 +307,7 @@ public class InsertCoordinator extends AbstractMutationCoordinator {
|
||||||
return session.getFactory()
|
return session.getFactory()
|
||||||
.getServiceRegistry()
|
.getServiceRegistry()
|
||||||
.getService( MutationExecutorService.class )
|
.getService( MutationExecutorService.class )
|
||||||
.createExecutor( ( !dynamicUpdate && session.getTransactionCoordinator() != null &&
|
.createExecutor( resolveBatchKeyAccess( dynamicUpdate, session ), group, session );
|
||||||
session.getTransactionCoordinator().isTransactionActive() ? () -> batchKey : () -> null ),
|
|
||||||
group, session );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static TableInclusionChecker getTableInclusionChecker(InsertValuesAnalysis insertValuesAnalysis) {
|
protected static TableInclusionChecker getTableInclusionChecker(InsertValuesAnalysis insertValuesAnalysis) {
|
||||||
|
@ -410,4 +410,12 @@ public class InsertCoordinator extends AbstractMutationCoordinator {
|
||||||
&& generator.generatedOnExecution()
|
&& generator.generatedOnExecution()
|
||||||
&& ( (OnExecutionGenerator) generator ).referenceColumnsInSql(dialect);
|
&& ( (OnExecutionGenerator) generator ).referenceColumnsInSql(dialect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getBatchKey()}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public BasicBatchKey getInsertBatchKey() {
|
||||||
|
return batchKey;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -970,9 +970,7 @@ public class UpdateCoordinatorStandard extends AbstractMutationCoordinator imple
|
||||||
return session.getSessionFactory()
|
return session.getSessionFactory()
|
||||||
.getServiceRegistry()
|
.getServiceRegistry()
|
||||||
.getService( MutationExecutorService.class )
|
.getService( MutationExecutorService.class )
|
||||||
.createExecutor( ( !dynamicUpdate && session.getTransactionCoordinator() != null &&
|
.createExecutor( resolveBatchKeyAccess( dynamicUpdate, session ), group, session );
|
||||||
session.getTransactionCoordinator().isTransactionActive() ? () -> batchKey : () -> null ),
|
|
||||||
group, session );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MutationOperationGroup generateDynamicUpdateGroup(
|
protected MutationOperationGroup generateDynamicUpdateGroup(
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
* 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.orm.test.batch;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.Generated;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.Setting;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Embeddable;
|
||||||
|
import jakarta.persistence.EmbeddedId;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.FetchType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.JoinColumn;
|
||||||
|
import jakarta.persistence.JoinColumns;
|
||||||
|
import jakarta.persistence.OneToOne;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
|
@SessionFactory
|
||||||
|
@DomainModel( annotatedClasses = {
|
||||||
|
BatchGeneratedAssociationTest.Interpretation.class,
|
||||||
|
BatchGeneratedAssociationTest.InterpretationData.class,
|
||||||
|
BatchGeneratedAssociationTest.InterpretationVersion.class
|
||||||
|
} )
|
||||||
|
@ServiceRegistry( settings = @Setting( name = AvailableSettings.STATEMENT_BATCH_SIZE, value = "10" ) )
|
||||||
|
public class BatchGeneratedAssociationTest {
|
||||||
|
@Test
|
||||||
|
public void test(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction( session -> {
|
||||||
|
final Long interpretationVersion = 111L;
|
||||||
|
|
||||||
|
final Interpretation interpretation = new Interpretation();
|
||||||
|
interpretation.uuid = 1L;
|
||||||
|
|
||||||
|
final InterpretationData interpretationData = new InterpretationData();
|
||||||
|
interpretationData.interpretationVersion = new InterpretationVersion(
|
||||||
|
interpretationVersion,
|
||||||
|
interpretation.uuid
|
||||||
|
);
|
||||||
|
interpretationData.name = "TEST_NAME";
|
||||||
|
session.persist( interpretationData );
|
||||||
|
|
||||||
|
interpretation.interpretationData = interpretationData;
|
||||||
|
interpretation.interpretationVersion = interpretationVersion;
|
||||||
|
session.persist( interpretation );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "Interpretation" )
|
||||||
|
@Table( name = "interpretations" )
|
||||||
|
public static class Interpretation {
|
||||||
|
@Id
|
||||||
|
public Long uuid;
|
||||||
|
|
||||||
|
@Column( name = "interpretation_version" )
|
||||||
|
public Long interpretationVersion;
|
||||||
|
|
||||||
|
@Column( name = "id" )
|
||||||
|
@Generated
|
||||||
|
public Long id;
|
||||||
|
|
||||||
|
@OneToOne( fetch = FetchType.LAZY )
|
||||||
|
@JoinColumns( {
|
||||||
|
@JoinColumn( name = "uuid", referencedColumnName = "interpretation_uuid", insertable = false, updatable = false ),
|
||||||
|
@JoinColumn( name = "interpretation_version", referencedColumnName = "interpretation_version", insertable = false, updatable = false )
|
||||||
|
} )
|
||||||
|
public InterpretationData interpretationData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public static class InterpretationVersion implements Serializable {
|
||||||
|
@Column( name = "interpretation_version", nullable = false, updatable = false )
|
||||||
|
public Long version;
|
||||||
|
|
||||||
|
@Column( name = "interpretation_uuid", nullable = false, updatable = false )
|
||||||
|
public Long uuid;
|
||||||
|
|
||||||
|
public InterpretationVersion() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public InterpretationVersion(Long version, Long uuid) {
|
||||||
|
this.version = version;
|
||||||
|
this.uuid = uuid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "InterpretationData" )
|
||||||
|
@Table( name = "interpretation_data" )
|
||||||
|
public static class InterpretationData {
|
||||||
|
@EmbeddedId
|
||||||
|
public InterpretationVersion interpretationVersion;
|
||||||
|
|
||||||
|
@Column( updatable = false )
|
||||||
|
public String name;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue