Skip to content

Error when inserting in batch with joined table inheritance #2141

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,22 @@ org.gradle.java.installations.auto-download=false
#db = MSSQL

# Enable the SonatypeOS maven repository (mainly for Vert.x snapshots) when present (value ignored)
#enableSonatypeOpenSourceSnapshotsRep = true
enableSonatypeOpenSourceSnapshotsRep = true

# Enable the maven local repository (for local development when needed) when present (value ignored)
#enableMavenLocalRepo = true

# The default Hibernate ORM version (override using `-PhibernateOrmVersion=the.version.you.want`)
hibernateOrmVersion = 7.0.0.Beta4
hibernateOrmVersion = 7.0.0-SNAPSHOT

# Override default Hibernate ORM Gradle plugin version
# Using the stable version because I don't know how to configure the build to download the snapshot version from
# a remote repository
#hibernateOrmGradlePluginVersion = 7.0.0.Beta4
hibernateOrmGradlePluginVersion = 7.0.0.Beta4

# If set to true, skip Hibernate ORM version parsing (default is true, if set to null)
# this is required when using intervals or weird versions or the build will fail
#skipOrmVersionParsing = true
skipOrmVersionParsing = true

# Override default Vert.x Sql client version
#vertxSqlClientVersion = 4.5.13-SNAPSHOT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@
*/
package org.hibernate.reactive.engine.jdbc.mutation.internal;

import java.lang.invoke.MethodHandles;
import java.sql.SQLException;
import java.util.concurrent.CompletionStage;

import org.hibernate.engine.jdbc.batch.spi.Batch;
import org.hibernate.engine.jdbc.mutation.JdbcValueBindings;
import org.hibernate.engine.jdbc.mutation.OperationResultChecker;
Expand All @@ -25,6 +21,7 @@
import org.hibernate.persister.entity.mutation.EntityTableMapping;
import org.hibernate.reactive.adaptor.impl.PrepareStatementDetailsAdaptor;
import org.hibernate.reactive.adaptor.impl.PreparedStatementAdaptor;
import org.hibernate.reactive.engine.jdbc.ResultsCheckerUtil;
import org.hibernate.reactive.engine.jdbc.env.internal.ReactiveMutationExecutor;
import org.hibernate.reactive.generator.values.ReactiveGeneratedValuesMutationDelegate;
import org.hibernate.reactive.logging.impl.Log;
Expand All @@ -37,9 +34,16 @@
import org.hibernate.sql.model.TableMapping;
import org.hibernate.sql.model.ValuesAnalysis;

import java.lang.invoke.MethodHandles;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletionStage;

import static org.hibernate.engine.jdbc.mutation.internal.ModelMutationHelper.checkResults;
import static org.hibernate.reactive.logging.impl.LoggerFactory.make;
import static org.hibernate.reactive.util.impl.CompletionStages.failedFuture;
import static org.hibernate.reactive.util.impl.CompletionStages.loop;
import static org.hibernate.reactive.util.impl.CompletionStages.nullFuture;
import static org.hibernate.reactive.util.impl.CompletionStages.voidFuture;
import static org.hibernate.sql.model.ModelMutationLogging.MODEL_MUTATION_LOGGER;
Expand Down Expand Up @@ -73,10 +77,64 @@ private ReactiveConnection connection(SharedSessionContractImplementor session)
@Override
public CompletionStage<Void> performReactiveBatchedOperations(
ValuesAnalysis valuesAnalysis,
TableInclusionChecker inclusionChecker, OperationResultChecker resultChecker,
TableInclusionChecker inclusionChecker,
OperationResultChecker resultChecker,
SharedSessionContractImplementor session) {
return ReactiveMutationExecutor.super
.performReactiveBatchedOperations( valuesAnalysis, inclusionChecker, resultChecker, session);
final PreparedStatementGroup batchedMutationOperationGroup = getBatchedPreparedStatementGroup();
if ( batchedMutationOperationGroup != null ) {
final List<PreparedStatementDetails> preparedStatementDetailsList = new ArrayList<>(
batchedMutationOperationGroup.getNumberOfStatements() );
batchedMutationOperationGroup.forEachStatement( (tableName, statementDetails) -> preparedStatementDetailsList
.add( statementDetails ) );
return loop( preparedStatementDetailsList, statementDetails -> {
if ( statementDetails == null ) {
return voidFuture();
}
final JdbcValueBindings valueBindings = getJdbcValueBindings();
final TableMapping tableDetails = statementDetails.getMutatingTableDetails();
if ( inclusionChecker != null && !inclusionChecker.include( tableDetails ) ) {
if ( MODEL_MUTATION_LOGGER.isTraceEnabled() ) {
MODEL_MUTATION_LOGGER.tracef(
"Skipping execution of secondary insert : %s",
tableDetails.getTableName()
);
}
return voidFuture();
}

// If we get here the statement is needed - make sure it is resolved
final Object[] paramValues = PreparedStatementAdaptor.bind( statement -> {
PreparedStatementDetails details = new PrepareStatementDetailsAdaptor(
statementDetails,
statement,
session.getJdbcServices()
);
valueBindings.beforeStatement( details );
} );

final ReactiveConnection reactiveConnection = ( (ReactiveConnectionSupplier) session ).getReactiveConnection();
final String sql = statementDetails.getSqlString();
return reactiveConnection.update(
sql,
paramValues,
true,
(rowCount, batchPosition, query) -> ResultsCheckerUtil.checkResults(
session,
statementDetails,
resultChecker,
rowCount,
batchPosition
)
).whenComplete( (o, throwable) -> { //TODO: is this part really needed?
if ( statementDetails.getStatement() != null ) {
statementDetails.releaseStatement( session );
}
valueBindings.afterStatement( tableDetails );
} );
}
);
}
return voidFuture();
}

@Override
Expand Down Expand Up @@ -159,6 +217,22 @@ public CompletionStage<GeneratedValues> performReactiveNonBatchedOperations(
}
}

public CompletionStage<Void> performReactiveSelfExecutingOperations(
ValuesAnalysis valuesAnalysis,
TableInclusionChecker inclusionChecker,
SharedSessionContractImplementor session) {
if ( getSelfExecutingMutations() == null || getSelfExecutingMutations().isEmpty() ) {
return voidFuture();
}

return loop( getSelfExecutingMutations(), operation -> {
if ( inclusionChecker.include( operation.getTableDetails() ) ) {
operation.performMutation( getJdbcValueBindings(), valuesAnalysis, session );
}
return voidFuture();
});
}

private class OperationsForEach {

private final Object id;
Expand Down Expand Up @@ -210,6 +284,7 @@ public CompletionStage<Void> buildLoop() {
return loop;
}
}

@Override
public CompletionStage<Void> performReactiveNonBatchedMutation(
PreparedStatementDetails statementDetails,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -436,11 +436,8 @@ protected CompletionStage<Void> deleteEntity(
persister
).nullifyTransientReferences( entityEntry.getDeletedState() )
.thenAccept( vv -> {
new Nullability( session ).checkNullability(
entityEntry.getDeletedState(),
persister,
Nullability.NullabilityCheckType.DELETE
);
new Nullability( session, Nullability.NullabilityCheckType.DELETE )
.checkNullability( entityEntry.getDeletedState(), persister );
persistenceContext.registerNullifiableEntityKey( key );

final ReactiveActionQueue actionQueue = actionQueue( session );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ public <R> MutationQuery createQuery(CriteriaDelete<R> criteriaDelete) {

@Override
public <R> Query<R> createNamedQuery(String queryName) {
return new MutinyQueryImpl<>( delegate.createReactiveNamedQuery( queryName, null ), factory );
return new MutinyQueryImpl<>( delegate.createReactiveNamedQuery( queryName ), factory );
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public Mutiny.MutationQuery createMutationQuery(String queryString) {

@Override
public <R> Query<R> createNamedQuery(String queryName) {
return new MutinyQueryImpl<>( delegate.createReactiveNamedQuery( queryName, null ), factory );
return new MutinyQueryImpl<>( delegate.createReactiveNamedQuery( queryName ), factory );
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*/
package org.hibernate.reactive.query;

import java.io.Serializable;
import java.time.Instant;
import java.util.Calendar;
import java.util.Collection;
Expand All @@ -23,12 +22,6 @@

public interface ReactiveQueryImplementor<R> extends ReactiveQuery<R> {

void setOptionalId(Serializable id);

void setOptionalEntityName(String entityName);

void setOptionalObject(Object optionalObject);

QueryParameterBindings getParameterBindings();

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import org.hibernate.graph.GraphSemantic;
import org.hibernate.graph.RootGraph;
import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.internal.AbstractSharedSessionContract;
import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.query.BindableType;
import org.hibernate.query.Order;
Expand Down Expand Up @@ -65,8 +64,18 @@ public class ReactiveNativeQueryImpl<R> extends NativeQueryImpl<R>

private final ReactiveAbstractSelectionQuery<R> selectionQueryDelegate;

public ReactiveNativeQueryImpl(String memento, SharedSessionContractImplementor session) {
super( memento, session );
public ReactiveNativeQueryImpl(String sql, SharedSessionContractImplementor session) {
super( sql, null, session );
this.selectionQueryDelegate = createSelectionQueryDelegate( session );
}

public ReactiveNativeQueryImpl(String sql, Class<R> resultClass, SharedSessionContractImplementor session) {
super( sql, resultClass, session );
this.selectionQueryDelegate = createSelectionQueryDelegate( session );
}

public ReactiveNativeQueryImpl(String sql, NamedResultSetMappingMemento resultSetMappingMemento, Class<R> resultClass, SharedSessionContractImplementor session) {
super( sql, resultSetMappingMemento, resultClass, session);
this.selectionQueryDelegate = createSelectionQueryDelegate( session );
}

Expand All @@ -91,14 +100,6 @@ public ReactiveNativeQueryImpl(
this.selectionQueryDelegate = createSelectionQueryDelegate( session );
}

public ReactiveNativeQueryImpl(
String sqlString,
NamedResultSetMappingMemento resultSetMappingMemento,
AbstractSharedSessionContract session) {
super( sqlString, resultSetMappingMemento, session );
this.selectionQueryDelegate = createSelectionQueryDelegate( session );
}

// Convenient for passing parameters to ReactiveAbstractSelectionQuery using method reference
private <T> T getNull() {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.tree.AbstractUpdateOrDeleteStatement;
import org.hibernate.sql.ast.tree.MutationStatement;
import org.hibernate.sql.ast.tree.expression.ColumnReference;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.expression.JdbcLiteral;
import org.hibernate.sql.ast.tree.from.MutatingTableReferenceGroupWrapper;
import org.hibernate.sql.ast.tree.from.NamedTableReference;
import org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate;
Expand Down Expand Up @@ -95,29 +93,28 @@ protected SqlAstTranslator<? extends JdbcOperationQueryMutation> createTranslato
return factory.getJdbcServices()
.getJdbcEnvironment()
.getSqlAstTranslatorFactory()
.buildMutationTranslator( factory, mutationStatement() );
.buildMutationTranslator( factory, createDeleteAst() );
}

private MutationStatement mutationStatement() {
// Copy and paste from superclass
private MutationStatement createDeleteAst() {
final MutationStatement ast;
if ( entityDescriptor.getSoftDeleteMapping() == null ) {
return sqmInterpretation.getSqlAst();
ast = sqmInterpretation.getSqlAst();
}
final AbstractUpdateOrDeleteStatement sqlDeleteAst = sqmInterpretation.getSqlAst();
final NamedTableReference targetTable = sqlDeleteAst.getTargetTable();
final SoftDeleteMapping columnMapping = getEntityDescriptor().getSoftDeleteMapping();
final ColumnReference columnReference = new ColumnReference( targetTable, columnMapping );
//noinspection rawtypes,unchecked
final JdbcLiteral jdbcLiteral = new JdbcLiteral(
columnMapping.getDeletedLiteralValue(),
columnMapping.getJdbcMapping()
);
final Assignment assignment = new Assignment( columnReference, jdbcLiteral );

return new UpdateStatement(
targetTable,
Collections.singletonList( assignment ),
sqlDeleteAst.getRestriction()
);
else {
final AbstractUpdateOrDeleteStatement sqlDeleteAst = sqmInterpretation.getSqlAst();
final NamedTableReference targetTable = sqlDeleteAst.getTargetTable();
final SoftDeleteMapping columnMapping = getEntityDescriptor().getSoftDeleteMapping();
final Assignment assignment = columnMapping.createSoftDeleteAssignment( targetTable );

ast = new UpdateStatement(
targetTable,
Collections.singletonList( assignment ),
sqlDeleteAst.getRestriction()
);
}
return ast;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ public interface ReactiveQueryProducer extends ReactiveConnectionSupplier {

<R> ReactiveQuery<R> createReactiveQuery(String queryString, Class<R> resultType);

<R> ReactiveQueryImplementor<R> createReactiveNamedQuery(String queryString);

<R> ReactiveQueryImplementor<R> createReactiveNamedQuery(String queryString, Class<R> resultType);

<R> ReactiveNativeQuery<R> createReactiveNativeQuery(String sqlString);
Expand Down
Loading
Loading