Skip to content

Commit b1d93d8

Browse files
committed
[hibernate#1867] Error when inserting in batch with joined table inheritance
1 parent d14ea11 commit b1d93d8

File tree

1 file changed

+82
-7
lines changed

1 file changed

+82
-7
lines changed

Diff for: hibernate-reactive-core/src/main/java/org/hibernate/reactive/engine/jdbc/mutation/internal/ReactiveMutationExecutorStandard.java

+82-7
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@
55
*/
66
package org.hibernate.reactive.engine.jdbc.mutation.internal;
77

8-
import java.lang.invoke.MethodHandles;
9-
import java.sql.SQLException;
10-
import java.util.concurrent.CompletionStage;
11-
128
import org.hibernate.engine.jdbc.batch.spi.Batch;
139
import org.hibernate.engine.jdbc.mutation.JdbcValueBindings;
1410
import org.hibernate.engine.jdbc.mutation.OperationResultChecker;
@@ -25,6 +21,7 @@
2521
import org.hibernate.persister.entity.mutation.EntityTableMapping;
2622
import org.hibernate.reactive.adaptor.impl.PrepareStatementDetailsAdaptor;
2723
import org.hibernate.reactive.adaptor.impl.PreparedStatementAdaptor;
24+
import org.hibernate.reactive.engine.jdbc.ResultsCheckerUtil;
2825
import org.hibernate.reactive.engine.jdbc.env.internal.ReactiveMutationExecutor;
2926
import org.hibernate.reactive.generator.values.ReactiveGeneratedValuesMutationDelegate;
3027
import org.hibernate.reactive.logging.impl.Log;
@@ -37,9 +34,16 @@
3734
import org.hibernate.sql.model.TableMapping;
3835
import org.hibernate.sql.model.ValuesAnalysis;
3936

37+
import java.lang.invoke.MethodHandles;
38+
import java.sql.SQLException;
39+
import java.util.ArrayList;
40+
import java.util.List;
41+
import java.util.concurrent.CompletionStage;
42+
4043
import static org.hibernate.engine.jdbc.mutation.internal.ModelMutationHelper.checkResults;
4144
import static org.hibernate.reactive.logging.impl.LoggerFactory.make;
4245
import static org.hibernate.reactive.util.impl.CompletionStages.failedFuture;
46+
import static org.hibernate.reactive.util.impl.CompletionStages.loop;
4347
import static org.hibernate.reactive.util.impl.CompletionStages.nullFuture;
4448
import static org.hibernate.reactive.util.impl.CompletionStages.voidFuture;
4549
import static org.hibernate.sql.model.ModelMutationLogging.MODEL_MUTATION_LOGGER;
@@ -73,10 +77,64 @@ private ReactiveConnection connection(SharedSessionContractImplementor session)
7377
@Override
7478
public CompletionStage<Void> performReactiveBatchedOperations(
7579
ValuesAnalysis valuesAnalysis,
76-
TableInclusionChecker inclusionChecker, OperationResultChecker resultChecker,
80+
TableInclusionChecker inclusionChecker,
81+
OperationResultChecker resultChecker,
7782
SharedSessionContractImplementor session) {
78-
return ReactiveMutationExecutor.super
79-
.performReactiveBatchedOperations( valuesAnalysis, inclusionChecker, resultChecker, session);
83+
final PreparedStatementGroup batchedMutationOperationGroup = getBatchedPreparedStatementGroup();
84+
if ( batchedMutationOperationGroup != null ) {
85+
final List<PreparedStatementDetails> preparedStatementDetailsList = new ArrayList<>(
86+
batchedMutationOperationGroup.getNumberOfStatements() );
87+
batchedMutationOperationGroup.forEachStatement( (tableName, statementDetails) -> preparedStatementDetailsList
88+
.add( statementDetails ) );
89+
loop( preparedStatementDetailsList, statementDetails -> {
90+
if ( statementDetails == null ) {
91+
return voidFuture();
92+
}
93+
final JdbcValueBindings valueBindings = getJdbcValueBindings();
94+
final TableMapping tableDetails = statementDetails.getMutatingTableDetails();
95+
if ( inclusionChecker != null && !inclusionChecker.include( tableDetails ) ) {
96+
if ( MODEL_MUTATION_LOGGER.isTraceEnabled() ) {
97+
MODEL_MUTATION_LOGGER.tracef(
98+
"Skipping execution of secondary insert : %s",
99+
tableDetails.getTableName()
100+
);
101+
}
102+
return voidFuture();
103+
}
104+
105+
// If we get here the statement is needed - make sure it is resolved
106+
final Object[] paramValues = PreparedStatementAdaptor.bind( statement -> {
107+
PreparedStatementDetails details = new PrepareStatementDetailsAdaptor(
108+
statementDetails,
109+
statement,
110+
session.getJdbcServices()
111+
);
112+
valueBindings.beforeStatement( details );
113+
} );
114+
115+
final ReactiveConnection reactiveConnection = ( (ReactiveConnectionSupplier) session ).getReactiveConnection();
116+
final String sql = statementDetails.getSqlString();
117+
return reactiveConnection.update(
118+
sql,
119+
paramValues,
120+
true,
121+
(rowCount, batchPosition, query) -> ResultsCheckerUtil.checkResults(
122+
session,
123+
statementDetails,
124+
resultChecker,
125+
rowCount,
126+
batchPosition
127+
)
128+
).whenComplete( (o, throwable) -> { //TODO: is this part really needed?
129+
if ( statementDetails.getStatement() != null ) {
130+
statementDetails.releaseStatement( session );
131+
}
132+
valueBindings.afterStatement( tableDetails );
133+
} );
134+
}
135+
);
136+
}
137+
return voidFuture();
80138
}
81139

82140
@Override
@@ -159,6 +217,22 @@ public CompletionStage<GeneratedValues> performReactiveNonBatchedOperations(
159217
}
160218
}
161219

220+
public CompletionStage<Void> performReactiveSelfExecutingOperations(
221+
ValuesAnalysis valuesAnalysis,
222+
TableInclusionChecker inclusionChecker,
223+
SharedSessionContractImplementor session) {
224+
if ( getSelfExecutingMutations() == null || getSelfExecutingMutations().isEmpty() ) {
225+
return voidFuture();
226+
}
227+
228+
return loop( getSelfExecutingMutations(), operation -> {
229+
if ( inclusionChecker.include( operation.getTableDetails() ) ) {
230+
operation.performMutation( getJdbcValueBindings(), valuesAnalysis, session );
231+
}
232+
return voidFuture();
233+
});
234+
}
235+
162236
private class OperationsForEach {
163237

164238
private final Object id;
@@ -210,6 +284,7 @@ public CompletionStage<Void> buildLoop() {
210284
return loop;
211285
}
212286
}
287+
213288
@Override
214289
public CompletionStage<Void> performReactiveNonBatchedMutation(
215290
PreparedStatementDetails statementDetails,

0 commit comments

Comments
 (0)