Skip to content

Commit

Permalink
HHH-16386 - Disable batching for dynamic-insert and dynamic-update
Browse files Browse the repository at this point in the history
Signed-off-by: Jan Schatteman <jschatte@redhat.com>
  • Loading branch information
jrenaat authored and sebersole committed Mar 28, 2023
1 parent 0455e2d commit 1b86b22
Show file tree
Hide file tree
Showing 4 changed files with 372 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ protected Object doStaticInserts(Object id, Object[] values, Object object, Shar

final TableInclusionChecker tableInclusionChecker = getTableInclusionChecker( insertValuesAnalysis );

final MutationExecutor mutationExecutor = executor( session, staticInsertGroup );
final MutationExecutor mutationExecutor = executor( session, staticInsertGroup, false );

decomposeForInsert(
mutationExecutor,
Expand Down Expand Up @@ -271,7 +271,7 @@ protected Object doDynamicInserts(Object id, Object[] values, Object object, Sha
final boolean[] insertability = getPropertiesToInsert( values );
final MutationOperationGroup insertGroup = generateDynamicInsertSqlGroup( insertability );

final MutationExecutor mutationExecutor = executor( session, insertGroup );
final MutationExecutor mutationExecutor = executor( session, insertGroup, true );

final InsertValuesAnalysis insertValuesAnalysis = new InsertValuesAnalysis( entityPersister(), values );

Expand Down Expand Up @@ -301,11 +301,11 @@ protected Object doDynamicInserts(Object id, Object[] values, Object object, Sha
}
}

private MutationExecutor executor(SharedSessionContractImplementor session, MutationOperationGroup group) {
private MutationExecutor executor(SharedSessionContractImplementor session, MutationOperationGroup group, boolean dynamicUpdate) {
return session.getFactory()
.getServiceRegistry()
.getService( MutationExecutorService.class )
.createExecutor( ( session.getTransactionCoordinator() != null &&
.createExecutor( ( !dynamicUpdate && session.getTransactionCoordinator() != null &&
session.getTransactionCoordinator().isTransactionActive() ? () -> batchKey : () -> null ),
group, session );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ protected void doVersionUpdate(

final EntityTableMapping mutatingTableDetails = (EntityTableMapping) versionUpdateGroup.getSingleOperation().getTableDetails();

final MutationExecutor mutationExecutor = executor( session, versionUpdateGroup );
final MutationExecutor mutationExecutor = executor( session, versionUpdateGroup, false );

final EntityVersionMapping versionMapping = entityPersister().getVersionMapping();

Expand Down Expand Up @@ -703,7 +703,7 @@ protected void doStaticUpdate(
UpdateValuesAnalysisImpl valuesAnalysis,
SharedSessionContractImplementor session) {

final MutationExecutor mutationExecutor = executor( session, staticUpdateGroup );
final MutationExecutor mutationExecutor = executor( session, staticUpdateGroup, false );

decomposeForUpdate(
id,
Expand Down Expand Up @@ -921,7 +921,7 @@ protected void doDynamicUpdate(

// and then execute them

final MutationExecutor mutationExecutor = executor( session, dynamicUpdateGroup );
final MutationExecutor mutationExecutor = executor( session, dynamicUpdateGroup, true );

decomposeForUpdate(
id,
Expand Down Expand Up @@ -966,11 +966,11 @@ protected void doDynamicUpdate(
}
}

private MutationExecutor executor(SharedSessionContractImplementor session, MutationOperationGroup group) {
private MutationExecutor executor(SharedSessionContractImplementor session, MutationOperationGroup group, boolean dynamicUpdate) {
return session.getSessionFactory()
.getServiceRegistry()
.getService( MutationExecutorService.class )
.createExecutor( ( session.getTransactionCoordinator() != null &&
.createExecutor( ( !dynamicUpdate && session.getTransactionCoordinator() != null &&
session.getTransactionCoordinator().isTransactionActive() ? () -> batchKey : () -> null ),
group, session );
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
/*
* 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.util.List;

import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;

import org.hibernate.testing.jdbc.SQLStatementInspector;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.FailureExpected;
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.AfterEach;
import org.junit.jupiter.api.Test;

import jakarta.persistence.Basic;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Inheritance;
import jakarta.persistence.PrimaryKeyJoinColumn;
import jakarta.persistence.Table;

import static jakarta.persistence.InheritanceType.JOINED;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hibernate.cfg.AvailableSettings.STATEMENT_BATCH_SIZE;

/**
* @author Steve Ebersole
*/
public class BatchedMultiTableDynamicStatementTests {

@Test
@ServiceRegistry( settings = @Setting( name = STATEMENT_BATCH_SIZE, value = "2" ) )
@DomainModel( annotatedClasses = { Payment.class, CheckPayment.class } )
@SessionFactory( useCollectingStatementInspector = true )
public void testBatched(SessionFactoryScope scope) {
final SQLStatementInspector statementCollector = scope.getCollectingStatementInspector();
statementCollector.clear();

createData( scope );

assertThat( statementCollector.getSqlQueries() ).hasSize( 6 );

scope.inTransaction( (session) -> {
final List<Payment> payments = session.createSelectionQuery( "from Payment", Payment.class ).list();
assertThat( payments ).hasSize( 3 );
} );
}

@Test
@ServiceRegistry( settings = @Setting( name = STATEMENT_BATCH_SIZE, value = "-1" ) )
@DomainModel( annotatedClasses = { Payment.class, CheckPayment.class } )
@SessionFactory( useCollectingStatementInspector = true )
public void testNonBatched(SessionFactoryScope scope) {
final SQLStatementInspector statementCollector = scope.getCollectingStatementInspector();
statementCollector.clear();

createData( scope );

assertThat( statementCollector.getSqlQueries() ).hasSize( 6 );

scope.inTransaction( (session) -> {
final List<Payment> payments = session.createSelectionQuery( "from Payment", Payment.class ).list();
assertThat( payments ).hasSize( 3 );
} );
}

private static void createData(SessionFactoryScope scope) {
final CheckPayment payment = new CheckPayment();
payment.setId( 1 );
payment.setAmount( 123.00 );
payment.setRoute( "0123-45-6789" );
payment.setAccount( "0089654321" );

final CheckPayment payment2 = new CheckPayment();
payment2.setId( 2 );
payment2.setAmount( 230.00 );
payment2.setRoute( "0123-45-6789" );
payment2.setAccount( "0089654321" );
payment2.setMemo( "Car Loan" );

final CheckPayment payment3 = new CheckPayment();
payment3.setId( 3 );
payment3.setAmount( 1234.00 );
payment3.setRoute( "0123-45-6789" );
payment3.setAccount( "0089654321" );

scope.inTransaction( (session) -> {
session.persist( payment );
session.persist( payment2 );
session.persist( payment3 );
} );
}

@AfterEach
public void dropTestData(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
session.createMutationQuery( "delete Payment" ).executeUpdate();
} );
}

@Entity( name = "Payment" )
@Table( name = "payments" )
@Inheritance( strategy = JOINED )
@DynamicInsert @DynamicUpdate
public static class Payment {
@Id
private Integer id;
private double amount;
private String comment;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public double getAmount() {
return amount;
}

public void setAmount(double amount) {
this.amount = amount;
}

public String getComment() {
return comment;
}

public void setComment(String comment) {
this.comment = comment;
}
}

@Entity( name = "CheckPayment")
@Table( name = "check_payments" )
@PrimaryKeyJoinColumn( name = "payment_fk" )
@DynamicInsert
@DynamicUpdate
public static class CheckPayment extends Payment {
@Basic(optional = false)
private String route;
@Basic(optional = false)
private String account;
private String memo;

public String getRoute() {
return route;
}

public void setRoute(String route) {
this.route = route;
}

public String getAccount() {
return account;
}

public void setAccount(String account) {
this.account = account;
}

public String getMemo() {
return memo;
}

public void setMemo(String memo) {
this.memo = memo;
}
}
}

0 comments on commit 1b86b22

Please sign in to comment.