[jOOQ/jOOQ#8544] ExecuteListener#end() not last lifecycle event when using DSLContext#fetchOne()

This commit is contained in:
Lukas Eder 2019-07-02 15:53:41 +02:00
parent 10735fdb50
commit bee81a3933
2 changed files with 33 additions and 12 deletions

View File

@ -143,6 +143,7 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
private transient boolean lazy;
private transient boolean many;
private transient Cursor<R> cursor;
private transient boolean autoclosing = true;
private Result<R> result;
private ResultsImpl results;
@ -316,7 +317,7 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
}
Field<?>[] fields = getFields(ctx.resultSet().getMetaData());
cursor = new CursorImpl<R>(ctx, listener, fields, intern.internIndexes(fields), keepStatement(), keepResultSet(), getRecordType(), SettingsTools.getMaxRows(maxRows, ctx.settings()));
cursor = new CursorImpl<R>(ctx, listener, fields, intern.internIndexes(fields), keepStatement(), keepResultSet(), getRecordType(), SettingsTools.getMaxRows(maxRows, ctx.settings()), autoclosing);
if (!lazy) {
result = cursor.fetch();
@ -386,7 +387,7 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
try {
if (c == null)
c = fetchLazy();
c = fetchLazyNonAutoClosing();
if (buffer == null)
buffer = new ArrayDeque<R>();
@ -457,7 +458,7 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
@Override
public final <X, A> X collect(Collector<? super R, A, X> collector) {
try (Cursor<R> c = fetchLazy()) {
try (Cursor<R> c = fetchLazyNonAutoClosing()) {
return c.collect(collector);
}
}
@ -469,6 +470,24 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
return fetchLazy(fetchSize);
}
/**
* When we manage the lifecycle of a returned {@link Cursor} internally in
* jOOQ, then the cursor must not be auto-closed.
*/
final Cursor<R> fetchLazyNonAutoClosing() {
final boolean previousAutoClosing = autoclosing;
// [#3515] TODO: Avoid modifying a Query's per-execution state
autoclosing = false;
try {
return fetchLazy();
}
finally {
autoclosing = previousAutoClosing;
}
}
@Override
@Deprecated
public final Cursor<R> fetchLazy(int size) {
@ -631,7 +650,7 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
@Override
public final R fetchOne() {
return Tools.fetchOne(fetchLazy(), hasLimit1());
return Tools.fetchOne(fetchLazyNonAutoClosing(), hasLimit1());
}
@Override
@ -726,7 +745,7 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
@Override
public final R fetchSingle() {
return Tools.fetchSingle(fetchLazy(), hasLimit1());
return Tools.fetchSingle(fetchLazyNonAutoClosing(), hasLimit1());
}
@Override
@ -912,7 +931,7 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
@Override
public final R fetchAny() {
Cursor<R> c = fetchLazy();
Cursor<R> c = fetchLazyNonAutoClosing();
try {
return c.fetchNext();

View File

@ -104,6 +104,7 @@ final class CursorImpl<R extends Record> extends AbstractCursor<R> implements Cu
private final boolean[] intern;
private final boolean keepResultSet;
private final boolean keepStatement;
private final boolean autoclosing;
private final int maxRows;
private final RecordFactory<? extends R> factory;
private boolean isClosed;
@ -123,10 +124,10 @@ final class CursorImpl<R extends Record> extends AbstractCursor<R> implements Cu
@SuppressWarnings("unchecked")
CursorImpl(ExecuteContext ctx, ExecuteListener listener, Field<?>[] fields, int[] internIndexes, boolean keepStatement, boolean keepResultSet) {
this(ctx, listener, fields, internIndexes, keepStatement, keepResultSet, (Class<? extends R>) RecordImpl.class, 0);
this(ctx, listener, fields, internIndexes, keepStatement, keepResultSet, (Class<? extends R>) RecordImpl.class, 0, true);
}
CursorImpl(ExecuteContext ctx, ExecuteListener listener, Field<?>[] fields, int[] internIndexes, boolean keepStatement, boolean keepResultSet, Class<? extends R> type, int maxRows) {
CursorImpl(ExecuteContext ctx, ExecuteListener listener, Field<?>[] fields, int[] internIndexes, boolean keepStatement, boolean keepResultSet, Class<? extends R> type, int maxRows, boolean autoclosing) {
super(ctx.configuration(), new Fields<R>(fields));
this.ctx = ctx;
@ -142,6 +143,7 @@ final class CursorImpl<R extends Record> extends AbstractCursor<R> implements Cu
this.maxRows = maxRows;
this.lockRowsForUpdate = TRUE.equals(ctx.data(DATA_LOCK_ROWS_FOR_UPDATE));
this.autoclosing = autoclosing;
if (internIndexes != null) {
this.intern = new boolean[fields.length];
@ -1630,10 +1632,10 @@ final class CursorImpl<R extends Record> extends AbstractCursor<R> implements Cu
throw ctx.exception();
}
// [#1868] [#2373] [#2385] This calls through to Utils.safeClose()
// if necessary, lazy-terminating the ExecuteListener lifecycle if
// the result is not eager-fetched.
if (record == null) {
// [#1868] [#2373] [#2385] [#8544] This calls through to
// Utils.safeClose() if necessary, lazy-terminating the ExecuteListener
// lifecycle if the result is not eager-fetched.
if (record == null && autoclosing) {
CursorImpl.this.close();
}