[jOOQ/jOOQ#15331] Batch::executeAsync throws NullPointerException when

executed with R2DBC driver
This commit is contained in:
Lukas Eder 2023-07-11 13:02:16 +02:00
parent 998c0148be
commit 22aa792884
3 changed files with 27 additions and 15 deletions

View File

@ -64,6 +64,7 @@ import static org.jooq.impl.Tools.consumeExceptions;
import static org.jooq.impl.Tools.BooleanDataKey.DATA_COUNT_BIND_VALUES;
import static org.jooq.impl.Tools.BooleanDataKey.DATA_FORCE_STATIC_STATEMENT;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@ -304,19 +305,7 @@ abstract class AbstractQuery<R extends Record> extends AbstractAttachableQueryPa
listener.renderEnd(ctx);
rendered.sql = ctx.sql();
// [#3234] Defer initialising of a connection until the prepare step
// This optimises unnecessary ConnectionProvider.acquire() calls when
// ControlFlowSignals are thrown
if (ctx.connection() == null)
if (ctx.configuration().connectionFactory() instanceof NoConnectionFactory)
throw new DetachedException("Cannot execute query. No JDBC Connection configured");
else
throw new DetachedException(
"Attempt to execute a blocking method (e.g. Query.execute() or ResultQuery.fetch()) "
+ "when only an R2BDC ConnectionFactory was configured. jOOQ's RowCountQuery and ResultQuery "
+ "extend Publisher, which allows for reactive streams implementations to subscribe to the "
+ "results of a jOOQ query. Simply embed your query in the stream, e.g. using Flux.from(query). "
+ "See also: https://www.jooq.org/doc/latest/manual/sql-execution/fetching/reactive-fetching/");
connection(ctx);
// [#7106] In some SQL dialects, starting a transaction requires JDBC interaction
if (this instanceof StartTransaction && SET_AUTOCOMMIT_ON_START_TRANSACTION.contains(ctx.dialect()))
@ -395,6 +384,26 @@ abstract class AbstractQuery<R extends Record> extends AbstractAttachableQueryPa
}
}
static final Connection connection(DefaultExecuteContext ctx) {
Connection result = ctx.connection();
// [#3234] Defer initialising of a connection until the prepare step
// This optimises unnecessary ConnectionProvider.acquire() calls when
// ControlFlowSignals are thrown
if (result == null)
if (ctx.configuration().connectionFactory() instanceof NoConnectionFactory)
throw new DetachedException("Cannot execute query. No JDBC Connection configured");
else
throw new DetachedException(
"Attempt to execute a blocking method (e.g. Query.execute() or ResultQuery.fetch()) "
+ "when only an R2BDC ConnectionFactory was configured. jOOQ's RowCountQuery and ResultQuery "
+ "extend Publisher, which allows for reactive streams implementations to subscribe to the "
+ "results of a jOOQ query. Simply embed your query in the stream, e.g. using Flux.from(query). "
+ "See also: https://www.jooq.org/doc/latest/manual/sql-execution/fetching/reactive-fetching/");
else
return result;
}
@Override
public final CompletionStage<Integer> executeAsync() {
return executeAsync(Tools.configuration(this).executorProvider().provide());

View File

@ -37,6 +37,8 @@
*/
package org.jooq.impl;
import static org.jooq.impl.AbstractQuery.connection;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.stream.IntStream;
@ -111,7 +113,7 @@ final class BatchMultiple extends AbstractBatch {
ctx.transformQueries(listener);
if (ctx.statement() == null)
ctx.statement(new SettingsEnabledPreparedStatement(ctx.connection()));
ctx.statement(new SettingsEnabledPreparedStatement(connection(ctx)));
// [#9295] use query timeout from settings
int t = SettingsTools.getQueryTimeout(0, ctx.settings());

View File

@ -40,6 +40,7 @@ package org.jooq.impl;
import static org.jooq.conf.ParamType.INLINED;
import static org.jooq.conf.SettingsTools.executeStaticStatements;
import static org.jooq.conf.SettingsTools.getBatchSize;
import static org.jooq.impl.AbstractQuery.connection;
import static org.jooq.impl.Tools.checkedFunction;
import static org.jooq.impl.Tools.chunks;
import static org.jooq.impl.Tools.fields;
@ -208,7 +209,7 @@ final class BatchSingle extends AbstractBatch implements BatchBindStep {
listener.prepareStart(ctx);
if (ctx.statement() == null)
ctx.statement(ctx.connection().prepareStatement(ctx.sql()));
ctx.statement(connection(ctx).prepareStatement(ctx.sql()));
listener.prepareEnd(ctx);
// [#9295] use query timeout from settings