select =
+ create().selectOne()
+ .from(
+ TBook(), TBook(), TBook(), TBook(),
+ TBook(), TBook(), TBook(), TBook(),
+ TBook(), TBook(), TBook(), TBook(),
+ TBook(), TBook(), TBook(), TBook(),
+ TBook(), TBook(), TBook(), TBook(),
+ TBook(), TBook(), TBook(), TBook(),
+ TBook(), TBook(), TBook(), TBook());
+
+ try {
+ new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ Thread.sleep(500);
+ }
+ catch (InterruptedException ignore) {}
+ select.cancel();
+ }
+ }).start();
+
+ // The fetch should never terminate, as the above thread should cancel it
+ select.fetch();
+ fail();
+ }
+ catch (DataAccessException expected) {}
+ }
}
diff --git a/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java b/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java
index 5860659089..54d21f1767 100644
--- a/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java
+++ b/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java
@@ -1781,6 +1781,11 @@ public abstract class jOOQAbstractTest<
new StatementTests(this).testKeepStatement();
}
+ @Test
+ public void testCancelStatement() throws Exception {
+ new StatementTests(this).testCancelStatement();
+ }
+
@Test
public void testVoid() {
// A final test case to clean up the test database
diff --git a/jOOQ/src/main/java/org/jooq/Query.java b/jOOQ/src/main/java/org/jooq/Query.java
index d11e91b80b..6050bb99f5 100644
--- a/jOOQ/src/main/java/org/jooq/Query.java
+++ b/jOOQ/src/main/java/org/jooq/Query.java
@@ -226,6 +226,19 @@ public interface Query extends QueryPart, Attachable {
* @throws DataAccessException If something went wrong closing the statement
* @see Statement#close()
*/
- Query close() throws DataAccessException;
+ void close() throws DataAccessException;
+
+ /**
+ * Cancel the underlying statement
+ *
+ * This cancels the query's underlying {@link Statement} or
+ * {@link PreparedStatement}. If there is no underlying open and running
+ * statement, this call is simply ignored.
+ *
+ * @throws DataAccessException If something went wrong cancelling the
+ * statement
+ * @see Statement#cancel()
+ */
+ void cancel() throws DataAccessException;
}
diff --git a/jOOQ/src/main/java/org/jooq/ResultQuery.java b/jOOQ/src/main/java/org/jooq/ResultQuery.java
index ea0c638547..a8f1bf68bf 100644
--- a/jOOQ/src/main/java/org/jooq/ResultQuery.java
+++ b/jOOQ/src/main/java/org/jooq/ResultQuery.java
@@ -934,12 +934,6 @@ public interface ResultQuery extends Query {
@Override
ResultQuery keepStatement(boolean keepStatement);
- /**
- * {@inheritDoc}
- */
- @Override
- ResultQuery close() throws DataAccessException;
-
/**
* Specify the maximum number of rows returned by the underlying
* {@link Statement}
diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractDelegatingSelect.java b/jOOQ/src/main/java/org/jooq/impl/AbstractDelegatingSelect.java
index f855311292..44d9d54daf 100644
--- a/jOOQ/src/main/java/org/jooq/impl/AbstractDelegatingSelect.java
+++ b/jOOQ/src/main/java/org/jooq/impl/AbstractDelegatingSelect.java
@@ -95,8 +95,13 @@ abstract class AbstractDelegatingSelect
}
@Override
- public final ResultQuery close() {
- return getDelegate().close();
+ public final void close() {
+ getDelegate().close();
+ }
+
+ @Override
+ public final void cancel() {
+ getDelegate().cancel();
}
@Override
diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java b/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java
index 0e8a5eff44..2c0885f542 100644
--- a/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java
+++ b/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java
@@ -52,7 +52,6 @@ import org.jooq.ExecuteContext;
import org.jooq.ExecuteListener;
import org.jooq.Param;
import org.jooq.Query;
-import org.jooq.exception.DataAccessException;
import org.jooq.exception.DetachedException;
import org.jooq.tools.JooqLogger;
@@ -169,18 +168,33 @@ abstract class AbstractQuery extends AbstractQueryPart implements Query, Attacha
* {@inheritDoc}
*/
@Override
- public Query close() throws DataAccessException {
+ public final void close() {
if (statement != null) {
try {
statement.close();
statement = null;
}
catch (SQLException e) {
- throw Util.translate(null, e);
+ throw Util.translate(sql, e);
}
}
+ }
- return this;
+ /**
+ * Subclasses may override this for covariant result types
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public final void cancel() {
+ if (statement != null) {
+ try {
+ statement.cancel();
+ }
+ catch (SQLException e) {
+ throw Util.translate(sql, e);
+ }
+ }
}
@SuppressWarnings("deprecation")
@@ -209,7 +223,7 @@ abstract class AbstractQuery extends AbstractQueryPart implements Query, Attacha
try {
// [#385] If a statement was previously kept open
- if (statement != null) {
+ if (keepStatement() && statement != null) {
ctx.sql(sql);
ctx.statement(statement);
}
@@ -220,17 +234,13 @@ abstract class AbstractQuery extends AbstractQueryPart implements Query, Attacha
ctx.sql(getSQL());
listener.renderEnd(ctx);
- if (keepStatement) {
- sql = ctx.sql();
- }
+ sql = ctx.sql();
listener.prepareStart(ctx);
prepare(ctx);
listener.prepareEnd(ctx);
- if (keepStatement) {
- statement = ctx.statement();
- }
+ statement = ctx.statement();
}
// [#1856] Set the query timeout onto the Statement
@@ -257,7 +267,12 @@ abstract class AbstractQuery extends AbstractQueryPart implements Query, Attacha
// ResultQuery.fetchLazy() needs to keep open resources
if (!keepResult()) {
- Util.safeClose(listener, ctx, keepStatement);
+ Util.safeClose(listener, ctx, keepStatement());
+ }
+
+ if (!keepStatement()) {
+ statement = null;
+ sql = null;
}
}
}
diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractResultQuery.java b/jOOQ/src/main/java/org/jooq/impl/AbstractResultQuery.java
index 2151eb5324..33de568e84 100644
--- a/jOOQ/src/main/java/org/jooq/impl/AbstractResultQuery.java
+++ b/jOOQ/src/main/java/org/jooq/impl/AbstractResultQuery.java
@@ -129,12 +129,6 @@ abstract class AbstractResultQuery extends AbstractQuery imple
return (ResultQuery) super.keepStatement(k);
}
- @SuppressWarnings("unchecked")
- @Override
- public final ResultQuery close() {
- return (ResultQuery) super.close();
- }
-
@Override
public final ResultQuery maxRows(int rows) {
this.maxRows = rows;
diff --git a/jOOQ/src/main/java/org/jooq/impl/DeleteImpl.java b/jOOQ/src/main/java/org/jooq/impl/DeleteImpl.java
index 7c80dca663..0aeff42a6e 100644
--- a/jOOQ/src/main/java/org/jooq/impl/DeleteImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/DeleteImpl.java
@@ -103,8 +103,13 @@ class DeleteImpl
}
@Override
- public final Query close() {
- return getDelegate().close();
+ public final void close() {
+ getDelegate().close();
+ }
+
+ @Override
+ public final void cancel() {
+ getDelegate().cancel();
}
@Override
diff --git a/jOOQ/src/main/java/org/jooq/impl/InsertImpl.java b/jOOQ/src/main/java/org/jooq/impl/InsertImpl.java
index 9906daa56f..56709f4086 100644
--- a/jOOQ/src/main/java/org/jooq/impl/InsertImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/InsertImpl.java
@@ -121,8 +121,13 @@ class InsertImpl
}
@Override
- public final Query close() {
- return getDelegate().close();
+ public final void close() {
+ getDelegate().close();
+ }
+
+ @Override
+ public final void cancel() {
+ getDelegate().cancel();
}
// -------------------------------------------------------------------------
diff --git a/jOOQ/src/main/java/org/jooq/impl/UpdateImpl.java b/jOOQ/src/main/java/org/jooq/impl/UpdateImpl.java
index 47bddbae3b..d2db7e0155 100644
--- a/jOOQ/src/main/java/org/jooq/impl/UpdateImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/UpdateImpl.java
@@ -108,8 +108,13 @@ final class UpdateImpl
}
@Override
- public final Query close() {
- return getDelegate().close();
+ public final void close() {
+ getDelegate().close();
+ }
+
+ @Override
+ public final void cancel() {
+ getDelegate().cancel();
}
@Override