diff --git a/src/main/java/com/avaje/ebean/config/dbplatform/DatabasePlatform.java b/src/main/java/com/avaje/ebean/config/dbplatform/DatabasePlatform.java
index 4ebad2729..54073bd84 100644
--- a/src/main/java/com/avaje/ebean/config/dbplatform/DatabasePlatform.java
+++ b/src/main/java/com/avaje/ebean/config/dbplatform/DatabasePlatform.java
@@ -63,6 +63,12 @@ public class DatabasePlatform {
protected boolean selectCountWithAlias;
+ /**
+ * If set then use the FORWARD ONLY hint when creating ResultSets for
+ * findIterate() and findVisit().
+ */
+ protected boolean forwardOnlyHintOnFindIterate;
+
/**
* Instantiates a new database platform.
*/
@@ -199,6 +205,24 @@ public class DatabasePlatform {
return idInExpandedForm;
}
+ /**
+ * Return true if the ResultSet TYPE_FORWARD_ONLY Hint should be used on
+ * findIterate() and findVisit() PreparedStatements.
+ *
+ * This specifically is required for MySql when processing large results.
+ *
+ */
+ public boolean isForwardOnlyHintOnFindIterate() {
+ return forwardOnlyHintOnFindIterate;
+ }
+
+ /**
+ * Set to true if the ResultSet TYPE_FORWARD_ONLY Hint should be used by default on findIterate PreparedStatements.
+ */
+ public void setForwardOnlyHintOnFindIterate(boolean forwardOnlyHintOnFindIterate) {
+ this.forwardOnlyHintOnFindIterate = forwardOnlyHintOnFindIterate;
+ }
+
/**
* Return the DB identity/sequence features for this platform.
*
diff --git a/src/main/java/com/avaje/ebean/config/dbplatform/MySqlPlatform.java b/src/main/java/com/avaje/ebean/config/dbplatform/MySqlPlatform.java
index fba60277e..c89f06a6e 100644
--- a/src/main/java/com/avaje/ebean/config/dbplatform/MySqlPlatform.java
+++ b/src/main/java/com/avaje/ebean/config/dbplatform/MySqlPlatform.java
@@ -31,6 +31,7 @@ public class MySqlPlatform extends DatabasePlatform {
this.openQuote = "`";
this.closeQuote = "`";
+ this.forwardOnlyHintOnFindIterate = true;
this.booleanDbType = Types.BIT;
dbTypeMap.put(Types.BIT, new DbType("tinyint(1) default 0"));
diff --git a/src/main/java/com/avaje/ebeaninternal/server/query/CQuery.java b/src/main/java/com/avaje/ebeaninternal/server/query/CQuery.java
index 0ad5c619c..40ab36f72 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/query/CQuery.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/query/CQuery.java
@@ -346,8 +346,8 @@ public class CQuery implements DbReadContext, CancelableQuery {
/**
* Prepare bind and execute query with Forward only hints.
*/
- public boolean prepareBindExecuteQueryForwardOnly() throws SQLException {
- return prepareBindExecuteQueryWithOption(true);
+ public boolean prepareBindExecuteQueryForwardOnly(boolean dbPlatformForwardOnlyHint) throws SQLException {
+ return prepareBindExecuteQueryWithOption(dbPlatformForwardOnlyHint);
}
/**
@@ -357,7 +357,7 @@ public class CQuery implements DbReadContext, CancelableQuery {
return prepareBindExecuteQueryWithOption(false);
}
- private boolean prepareBindExecuteQueryWithOption(boolean forward) throws SQLException {
+ private boolean prepareBindExecuteQueryWithOption(boolean forwardOnlyHint) throws SQLException {
synchronized (this) {
if (cancelled || query.isCancelled()) {
@@ -371,8 +371,9 @@ public class CQuery implements DbReadContext, CancelableQuery {
// prepare
SpiTransaction t = request.getTransaction();
Connection conn = t.getInternalConnection();
- if (forward) {
- // Hints required for mysql for large resultset processing (Issue 56)
+
+ if (forwardOnlyHint) {
+ // Use forward only hints for large resultset processing (Issue 56, MySql specific)
pstmt = conn.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
} else {
pstmt = conn.prepareStatement(sql);
diff --git a/src/main/java/com/avaje/ebeaninternal/server/query/CQueryEngine.java b/src/main/java/com/avaje/ebeaninternal/server/query/CQueryEngine.java
index 844f26af9..55757bb29 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/query/CQueryEngine.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/query/CQueryEngine.java
@@ -25,6 +25,8 @@ public class CQueryEngine {
private static final Logger logger = LoggerFactory.getLogger(CQueryEngine.class);
+ private final DatabasePlatform dbPlatform;
+
private final CQueryBuilder queryBuilder;
private final BackgroundExecutor backgroundExecutor;
@@ -33,6 +35,7 @@ public class CQueryEngine {
public CQueryEngine(DatabasePlatform dbPlatform, Binder binder, BackgroundExecutor backgroundExecutor) {
+ this.dbPlatform = dbPlatform;
this.backgroundExecutor = backgroundExecutor;
this.queryBuilder = new CQueryBuilder(backgroundExecutor, dbPlatform, binder);
}
@@ -122,7 +125,7 @@ public class CQueryEngine {
try {
- if (!cquery.prepareBindExecuteQueryForwardOnly()) {
+ if (!cquery.prepareBindExecuteQueryForwardOnly(dbPlatform.isForwardOnlyHintOnFindIterate())) {
// query has been cancelled already
logger.trace("Future fetch already cancelled");
return null;