Fix for #87 - v4 - Remove Query setBackgroundFetchAfter() feature

This commit is contained in:
Rob Bygrave
2014-04-20 19:30:40 +12:00
parent 18d9c53ce3
commit fc628d336d
29 changed files with 54 additions and 575 deletions
@@ -244,14 +244,6 @@ public interface ExpressionList<T> extends Serializable {
*/
public Query<T> setMaxRows(int maxRows);
/**
* Set the number of rows after which the fetching should continue in a
* background thread.
*
* @see Query#setBackgroundFetchAfter(int)
*/
public Query<T> setBackgroundFetchAfter(int backgroundFetchAfter);
/**
* Set the name of the property which values become the key of a map.
*
-7
View File
@@ -936,13 +936,6 @@ public interface Query<T> extends Serializable {
*/
public Query<T> setMaxRows(int maxRows);
/**
* Set the rows after which fetching should continue in a background thread.
*
* @param backgroundFetchAfter
*/
public Query<T> setBackgroundFetchAfter(int backgroundFetchAfter);
/**
* Set the property to use as keys for a map.
* <p>
@@ -3,11 +3,8 @@ package com.avaje.ebean.bean;
import java.io.Serializable;
import java.util.Collection;
import java.util.Set;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import com.avaje.ebean.ExpressionList;
import com.avaje.ebean.Query;
/**
* Lazy loading capable Maps, Lists and Sets.
@@ -75,30 +72,6 @@ public interface BeanCollection<E> extends Serializable {
*/
public void setFilterMany(ExpressionList<?> filterMany);
/**
* Set when this collection is being loaded via a background thread.
* <p>
* Refer to {@link Query#setBackgroundFetchAfter(int)}
* </p>
*/
public void setBackgroundFetch(Future<Integer> future);
/**
* Wait for the fetch to complete with a given timeout.
* <p>
* Refer to {@link Query#setBackgroundFetchAfter(int)}
* </p>
*/
public void backgroundFetchWait(long wait, TimeUnit timeUnit);
/**
* Wait for the fetch to complete.
* <p>
* Refer to {@link Query#setBackgroundFetchAfter(int)}
* </p>
*/
public void backgroundFetchWait();
/**
* Set a listener to be notified when the BeanCollection is first touched.
*/
@@ -174,18 +147,6 @@ public interface BeanCollection<E> extends Serializable {
*/
public void setHasMoreRows(boolean hasMoreRows);
/**
* Returns true if the fetch has finished. False if the fetch is continuing in
* a background thread.
*/
public boolean isFinishedFetch();
/**
* Set to true when a fetch has finished. Used when a fetch continues in the
* background.
*/
public void setFinishedFetch(boolean finishedFetch);
/**
* return true if there are real rows held. Return false is this is using
* Deferred fetch to lazy load the rows and the rows have not yet been
@@ -1,8 +1,6 @@
package com.avaje.ebean.common;
import java.util.Set;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import javax.persistence.PersistenceException;
@@ -37,8 +35,6 @@ public abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
protected transient BeanCollectionTouched beanCollectionTouched;
protected transient Future<Integer> fetchFuture;
/**
* The owning bean (used for lazy fetch).
*/
@@ -49,13 +45,6 @@ public abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
*/
protected final String propertyName;
/**
* Can be false when a background thread is used to continue the fetch the
* rows. It will set this to true when it is finished. If no background thread
* is used then this should already be true.
*/
protected boolean finishedFetch = true;
/**
* Flag set to true if rows are limited by firstRow maxRows and more rows
* exist. For use by client to enable 'next' for paging.
@@ -169,46 +158,6 @@ public abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
this.hasMoreRows = hasMoreRows;
}
/**
* Returns true if the fetch has finished. False if the fetch is continuing in
* a background thread.
*/
public boolean isFinishedFetch() {
return finishedFetch;
}
/**
* Set to true when a fetch has finished. Used when a fetch continues in the
* background.
*/
public void setFinishedFetch(boolean finishedFetch) {
this.finishedFetch = finishedFetch;
}
public void setBackgroundFetch(Future<Integer> fetchFuture) {
this.fetchFuture = fetchFuture;
}
public void backgroundFetchWait(long wait, TimeUnit timeUnit) {
if (fetchFuture != null) {
try {
fetchFuture.get(wait, timeUnit);
} catch (Exception e) {
throw new PersistenceException(e);
}
}
}
public void backgroundFetchWait() {
if (fetchFuture != null) {
try {
fetchFuture.get();
} catch (Exception e) {
throw new PersistenceException(e);
}
}
}
protected void checkReadOnly() {
if (readOnly) {
String msg = "This collection is in ReadOnly mode";
@@ -15,9 +15,10 @@ import com.avaje.ebean.bean.EntityBean;
/**
* List capable of lazy loading.
*/
public final class BeanList<E> extends AbstractBeanCollection<E> implements List<E>,
BeanCollectionAdd {
public final class BeanList<E> extends AbstractBeanCollection<E> implements List<E>, BeanCollectionAdd {
private static final long serialVersionUID = 1L;
/**
* The underlying List implementation.
*/
@@ -15,6 +15,8 @@ import com.avaje.ebean.bean.EntityBean;
*/
public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Map<K, E> {
private static final long serialVersionUID = 1L;
/**
* The underlying map implementation.
*/
@@ -15,6 +15,8 @@ import com.avaje.ebean.bean.EntityBean;
*/
public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E>, BeanCollectionAdd {
private static final long serialVersionUID = 1L;
/**
* The underlying Set implementation.
*/
@@ -508,12 +508,6 @@ public interface SpiQuery<T> extends Query<T> {
*/
public String getMapKey();
/**
* Return the number of rows after which fetching should occur in a
* background thread.
*/
public int getBackgroundFetchAfter();
/**
* Return the maximum number of rows to return in the query.
*/
@@ -544,14 +538,6 @@ public interface SpiQuery<T> extends Query<T> {
*/
public Object getId();
/**
* Return true if this query should use its own transaction.
* <p>
* This is true for background fetching and when using QueryListener.
* </p>
*/
public boolean createOwnTransaction();
/**
* Set the generated sql for debug purposes.
*
@@ -1137,7 +1137,7 @@ public final class DefaultServer implements SpiEbeanServer {
if (Mode.LAZYLOAD_MANY.equals(query.getMode())) {
allowOneManyFetch = false;
} else if (query.hasMaxRowsOrFirstRow() && !query.isRawSql() && !query.isSqlSelect() && query.getBackgroundFetchAfter() == 0) {
} else if (query.hasMaxRowsOrFirstRow() && !query.isRawSql() && !query.isSqlSelect()) {
// convert ALL fetch joins to Many's to be query joins
// so that limit offset type SQL clauses work
allowOneManyFetch = false;
@@ -6,9 +6,7 @@ import java.util.Map;
import com.avaje.ebean.ValuePair;
import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocOne;
import com.avaje.ebeaninternal.util.ValueUtil;
/**
* Helper to perform a diff given two beans of the same type.
@@ -116,7 +116,7 @@ public class InternalConfiguration {
this.transactionManager = new TransactionManager(clusterManager, backgroundExecutor,
serverConfig, beanDescriptorManager, this.getBootupClasses());
this.cQueryEngine = new CQueryEngine(serverConfig.getDatabasePlatform(), binder, backgroundExecutor);
this.cQueryEngine = new CQueryEngine(serverConfig.getDatabasePlatform(), binder);
ExternalTransactionManager externalTransactionManager = serverConfig.getExternalTransactionManager();
if (externalTransactionManager == null && serverConfig.isUseJtaTransactionManager()) {
@@ -55,13 +55,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements BeanQueryRe
private HashQueryPlan queryPlanHash;
/**
* Flag set if background fetching taking place. In this case the transaction
* is rolled back by the background fetching thread. Background fetching
* always takes place in its own transaction.
*/
private boolean backgroundFetching;
/**
* Create the InternalQueryRequest.
*/
@@ -163,12 +156,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements BeanQueryRe
@Override
public void initTransIfRequired() {
// first check if the query requires its own transaction
if (query.createOwnTransaction()) {
// using background fetch or query listener etc
transaction = ebeanServer.createQueryTransaction();
createdTransaction = true;
} else if (transaction == null) {
if (transaction == null) {
// maybe a current one
transaction = ebeanServer.getCurrentServerTransaction();
if (transaction == null) {
@@ -202,19 +190,12 @@ public final class OrmQueryRequest<T> extends BeanRequest implements BeanQueryRe
* </p>
*/
public void endTransIfRequired() {
if (createdTransaction && !backgroundFetching) {
if (createdTransaction) {
// we can rollback as readOnly transaction
transaction.rollback();
}
}
/**
* This query is using background fetching.
*/
public void setBackgroundFetching() {
backgroundFetching = true;
}
/**
* Return true if this is a find by id (rather than List Set or Map).
*/
@@ -2,7 +2,6 @@ package com.avaje.ebeaninternal.server.core;
import java.sql.SQLException;
import java.util.List;
import java.util.Set;
import javax.persistence.OptimisticLockException;
@@ -112,7 +112,6 @@ public final class BeanMapHelp<T> implements BeanCollectionHelp<T> {
return beanMap;
}
@SuppressWarnings("unchecked")
public void add(BeanCollection<?> collection, EntityBean bean) {
Object keyValue = beanProperty.getValueIntercept(bean);
@@ -374,10 +374,6 @@ abstract class JunctionExpression<T> implements Junction<T>, SpiExpression, Expr
return exprList.select(properties);
}
public com.avaje.ebean.Query<T> setBackgroundFetchAfter(int backgroundFetchAfter) {
return exprList.setBackgroundFetchAfter(backgroundFetchAfter);
}
public com.avaje.ebean.Query<T> setFirstRow(int firstRow) {
return exprList.setFirstRow(firstRow);
}
@@ -1,68 +0,0 @@
package com.avaje.ebeaninternal.server.query;
import java.util.concurrent.Callable;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebeaninternal.api.SpiTransaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Continue the fetch using a Background thread. The client knows when this has
* finished by checking to see if beanList.finishedFetch() is true.
*/
public class BackgroundFetch implements Callable<Integer> {
private static final Logger logger = LoggerFactory.getLogger(BackgroundFetch.class);
private final CQuery<?> cquery;
private final SpiTransaction transaction;
/**
* Create the BackgroundFetch.
*/
public BackgroundFetch(CQuery<?> cquery) {
this.cquery = cquery;
this.transaction = cquery.getTransaction();
}
/**
* Continue the fetch.
*/
public Integer call() {
try {
BeanCollection<?> bc = cquery.continueFetchingInBackground();
return bc.size();
} catch (Exception e) {
logger.error(null, e);
return Integer.valueOf(0);
} finally {
try {
cquery.close();
} catch (Exception e) {
logger.error(null, e);
}
try {
// we must have our own transaction for background fetching
// and this performs the rollback... returning the
// connection back into the connection pool.
transaction.rollback();
} catch (Exception e) {
logger.error(null, e);
}
}
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("BackgroundFetch ").append(cquery);
return sb.toString();
}
}
@@ -1,109 +0,0 @@
package com.avaje.ebeaninternal.server.query;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.concurrent.Callable;
import com.avaje.ebeaninternal.api.BeanIdList;
import com.avaje.ebeaninternal.api.SpiTransaction;
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
import com.avaje.ebeaninternal.server.deploy.DbReadContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Continue the fetch using a Background thread. The client knows when this has
* finished by checking to see if beanList.finishedFetch() is true.
*/
public class BackgroundIdFetch implements Callable<Integer> {
private static final Logger logger = LoggerFactory.getLogger(BackgroundIdFetch.class);
private final ResultSet rset;
private final PreparedStatement pstmt;
private final SpiTransaction transaction;
private final DbReadContext ctx;
private final BeanDescriptor<?> beanDescriptor;
private final BeanIdList idList;
/**
* Create the BackgroundFetch.
*/
public BackgroundIdFetch(SpiTransaction transaction,
ResultSet rset, PreparedStatement pstmt,
DbReadContext ctx, BeanDescriptor<?> beanDescriptor,
BeanIdList idList) {
this.ctx = ctx;
this.transaction = transaction;
this.rset = rset;
this.pstmt = pstmt;
this.beanDescriptor = beanDescriptor;
this.idList = idList;
}
/**
* Continue the fetch.
*/
public Integer call() {
try {
int startSize = idList.getIdList().size();
int rowsRead = 0;
while (rset.next()){
Object idValue = beanDescriptor.getIdBinder().read(ctx);
idList.add(idValue);
ctx.getDataReader().resetColumnPosition();
rowsRead++;
}
if (logger.isInfoEnabled()){
logger.info("BG FetchIds read:"+rowsRead+" total:"+(startSize+rowsRead));
}
return rowsRead;
} catch (Exception e) {
logger.error(null, e);
return 0;
} finally {
try {
close();
} catch (Exception e) {
logger.error(null, e);
}
try {
// we must have our own transaction for background fetching
// and this performs the rollback... returning the
// connection back into the connection pool.
transaction.rollback();
} catch (Exception e) {
logger.error(null, e);
}
}
}
private void close() {
try {
if (rset != null) {
rset.close();
}
} catch (SQLException e) {
logger.error(null, e);
}
try {
if (pstmt != null) {
pstmt.close();
}
} catch (SQLException e) {
logger.error(null, e);
}
}
}
@@ -185,15 +185,8 @@ public class CQuery<T> implements DbReadContext, CancelableQuery {
*/
private final ElPropertyValue manyPropertyEl;
private final int backgroundFetchAfter;
private final int maxRowsLimit;
/**
* Flag set when backgroundFetchAfter limit is hit.
*/
private boolean hasHitBackgroundFetchAfter;
private final PersistenceContext persistenceContext;
private DataReader dataReader;
@@ -272,12 +265,8 @@ public class CQuery<T> implements DbReadContext, CancelableQuery {
this.logWhereSql = queryPlan.getLogWhereSql();
this.desc = request.getBeanDescriptor();
this.predicates = predicates;
this.persistenceContext = request.getPersistenceContext();
this.maxRowsLimit = query.getMaxRows() > 0 ? query.getMaxRows() : GLOBAL_ROW_LIMIT;
this.backgroundFetchAfter = query.getBackgroundFetchAfter() > 0 ? query.getBackgroundFetchAfter() : Integer.MAX_VALUE;
this.help = createHelp(request);
this.collection = (BeanCollection<T>) (help != null ? help.createEmpty(false) : null);
}
@@ -535,26 +524,20 @@ public class CQuery<T> implements DbReadContext, CancelableQuery {
public boolean readBean() throws SQLException {
boolean result = readBeanInternal(true);
boolean result = readBeanInternal();
updateExecutionStatistics();
return result;
}
private boolean readBeanInternal(boolean inForeground) throws SQLException {
private boolean readBeanInternal() throws SQLException {
if (loadedBeanCount >= maxRowsLimit) {
collection.setHasMoreRows(hasMoreRows());
return false;
}
if (inForeground && loadedBeanCount >= backgroundFetchAfter) {
hasHitBackgroundFetchAfter = true;
collection.setFinishedFetch(false);
return false;
}
if (!manyIncluded) {
// simple query... no details...
return readRow();
@@ -629,15 +612,9 @@ public class CQuery<T> implements DbReadContext, CancelableQuery {
}
}
public BeanCollection<T> continueFetchingInBackground() throws SQLException {
readTheRows(false);
collection.setFinishedFetch(true);
return collection;
}
public BeanCollection<T> readCollection() throws SQLException {
readTheRows(true);
readTheRows();
updateExecutionStatistics();
@@ -670,17 +647,16 @@ public class CQuery<T> implements DbReadContext, CancelableQuery {
}
}
@SuppressWarnings("unchecked")
private void readTheRows(boolean inForeground) throws SQLException {
while (hasNextBean(inForeground)) {
private void readTheRows() throws SQLException {
while (hasNextBean()) {
// add to the list/set/map
help.add(collection, getLoadedBean());
}
}
protected boolean hasNextBean(boolean inForeground) throws SQLException {
protected boolean hasNextBean() throws SQLException {
if (!readBeanInternal(inForeground)) {
if (!readBeanInternal()) {
return false;
} else {
@@ -709,10 +685,6 @@ public class CQuery<T> implements DbReadContext, CancelableQuery {
request.getGraphContext().register(path, bc);
}
public boolean useBackgroundToContinueFetch() {
return hasHitBackgroundFetchAfter;
}
/**
* Return the query name.
*/
@@ -5,7 +5,6 @@ import java.util.Set;
import javax.persistence.PersistenceException;
import com.avaje.ebean.BackgroundExecutor;
import com.avaje.ebean.RawSql;
import com.avaje.ebean.RawSql.ColumnMapping;
import com.avaje.ebean.RawSql.ColumnMapping.Column;
@@ -44,8 +43,6 @@ public class CQueryBuilder implements Constants {
private final Binder binder;
private final BackgroundExecutor backgroundExecutor;
private final boolean selectCountWithAlias;
private DatabasePlatform dbPlatform;
@@ -53,9 +50,8 @@ public class CQueryBuilder implements Constants {
/**
* Create the SqlGenSelect.
*/
public CQueryBuilder(BackgroundExecutor backgroundExecutor, DatabasePlatform dbPlatform, Binder binder) {
public CQueryBuilder(DatabasePlatform dbPlatform, Binder binder) {
this.backgroundExecutor = backgroundExecutor;
this.binder = binder;
this.tableAliasPlaceHolder = GlobalProperties.get("ebean.tableAliasPlaceHolder", "${ta}");
this.columnAliasPrefix = GlobalProperties.get("ebean.columnAliasPrefix", "c");
@@ -103,8 +99,7 @@ public class CQueryBuilder implements Constants {
// skip building the SqlTree and Sql string
predicates.prepare(false);
String sql = queryPlan.getSql();
return new CQueryFetchIds(request, predicates, sql, backgroundExecutor);
return new CQueryFetchIds(request, predicates, sql);
}
// use RawSql or generated Sql
@@ -118,7 +113,7 @@ public class CQueryBuilder implements Constants {
queryPlan = new CQueryPlan(request, sql, sqlTree, false, s.isIncludesRowNumberColumn(), predicates.getLogWhereSql());
request.putQueryPlan(queryPlan);
return new CQueryFetchIds(request, predicates, sql, backgroundExecutor);
return new CQueryFetchIds(request, predicates, sql);
}
/**
@@ -1,12 +1,10 @@
package com.avaje.ebeaninternal.server.query;
import java.sql.SQLException;
import java.util.concurrent.FutureTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.avaje.ebean.BackgroundExecutor;
import com.avaje.ebean.QueryIterator;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.BeanCollectionTouched;
@@ -30,15 +28,11 @@ public class CQueryEngine {
private final CQueryBuilder queryBuilder;
private final BackgroundExecutor backgroundExecutor;
private final int defaultSecondaryQueryBatchSize = 100;
public CQueryEngine(DatabasePlatform dbPlatform, Binder binder, BackgroundExecutor backgroundExecutor) {
public CQueryEngine(DatabasePlatform dbPlatform, Binder binder) {
this.dbPlatform = dbPlatform;
this.backgroundExecutor = backgroundExecutor;
this.queryBuilder = new CQueryBuilder(backgroundExecutor, dbPlatform, binder);
this.queryBuilder = new CQueryBuilder(dbPlatform, binder);
}
public <T> CQuery<T> buildQuery(OrmQueryRequest<T> request) {
@@ -156,9 +150,6 @@ public class CQueryEngine {
*/
public <T> BeanCollection<T> findMany(OrmQueryRequest<T> request) {
// flag indicating whether we need to close the resources...
boolean useBackgroundToContinueFetch = false;
CQuery<T> cquery = queryBuilder.buildQuery(request);
request.setCancelableQuery(cquery);
@@ -182,18 +173,6 @@ public class CQueryEngine {
beanCollection.setBeanCollectionTouched(collectionTouched);
}
if (cquery.useBackgroundToContinueFetch()) {
// stop the request from putting connection back into pool
// before background fetching is finished.
request.setBackgroundFetching();
useBackgroundToContinueFetch = true;
BackgroundFetch fetch = new BackgroundFetch(cquery);
FutureTask<Integer> future = new FutureTask<Integer>(fetch);
beanCollection.setBackgroundFetch(future);
backgroundExecutor.execute(future);
}
if (request.isLogSummary()) {
logFindManySummary(cquery);
}
@@ -206,18 +185,14 @@ public class CQueryEngine {
throw cquery.createPersistenceException(e);
} finally {
if (useBackgroundToContinueFetch) {
// left closing resources to BackgroundFetch...
} else {
if (cquery != null) {
cquery.close();
}
if (request.getQuery().isFutureFetch()) {
// end the transaction for futureFindIds
// as it had it's own transaction
logger.debug("Future fetch completed!");
request.getTransaction().end();
}
if (cquery != null) {
cquery.close();
}
if (request.getQuery().isFutureFetch()) {
// end the transaction for futureFindIds
// as it had it's own transaction
logger.debug("Future fetch completed!");
request.getTransaction().end();
}
}
}
@@ -225,6 +200,7 @@ public class CQueryEngine {
/**
* Find and return a single bean using its unique id.
*/
@SuppressWarnings("unchecked")
public <T> T find(OrmQueryRequest<T> request) {
EntityBean bean = null;
@@ -8,9 +8,10 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.FutureTask;
import com.avaje.ebean.BackgroundExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebean.bean.EntityBeanIntercept;
@@ -27,8 +28,6 @@ import com.avaje.ebeaninternal.server.deploy.DbReadContext;
import com.avaje.ebeaninternal.server.type.DataBind;
import com.avaje.ebeaninternal.server.type.DataReader;
import com.avaje.ebeaninternal.server.type.RsetDataReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Executes the select row count query.
@@ -46,8 +45,6 @@ public class CQueryFetchIds {
private final SpiQuery<?> query;
private final BackgroundExecutor backgroundExecutor;
/**
* Where clause predicates.
*/
@@ -74,20 +71,16 @@ public class CQueryFetchIds {
private int rowCount;
private final int maxRows;
private final int bgFetchAfter;
/**
* Create the Sql select based on the request.
*/
public CQueryFetchIds(OrmQueryRequest<?> request, CQueryPredicates predicates,
String sql, BackgroundExecutor backgroundExecutor) {
public CQueryFetchIds(OrmQueryRequest<?> request, CQueryPredicates predicates, String sql) {
this.backgroundExecutor = backgroundExecutor;
this.request = request;
this.query = request.getQuery();
this.sql = sql;
this.maxRows = query.getMaxRows();
this.bgFetchAfter = query.getBackgroundFetchAfter();
query.setGeneratedSql(sql);
@@ -133,8 +126,6 @@ public class CQueryFetchIds {
*/
public BeanIdList findIds() throws SQLException {
boolean useBackgroundToContinueFetch = false;
startNano = System.nanoTime();
try {
@@ -185,9 +176,6 @@ public class CQueryFetchIds {
hasMoreRows = rset.next();
break;
} else if (bgFetchAfter > 0 && rowCount >= bgFetchAfter) {
useBackgroundToContinueFetch = true;
break;
}
}
@@ -195,31 +183,13 @@ public class CQueryFetchIds {
result.setHasMore(hasMoreRows);
}
if (useBackgroundToContinueFetch){
// tell the request not to end the transaction
// as we leave that up to the BackgroundIdFetch
request.setBackgroundFetching();
// submit background future task
BackgroundIdFetch bgFetch = new BackgroundIdFetch(t, rset, pstmt, ctx, desc, result);
FutureTask<Integer> future = new FutureTask<Integer>(bgFetch);
backgroundExecutor.execute(future);
// set on result so we can use the futureTask to wait
result.setBackgroundFetch(future);
}
long exeNano = System.nanoTime() - startNano;
executionTimeMicros = (int)exeNano/1000;
return result;
} finally {
if (useBackgroundToContinueFetch) {
// left closing resources to BackgroundFetch...
} else {
close();
}
close();
}
}
@@ -23,7 +23,7 @@ class CQueryIteratorSimple<T> implements QueryIterator<T> {
public boolean hasNext() {
try {
request.flushPersistenceContextOnIterate();
return cquery.hasNextBean(true);
return cquery.hasNextBean();
} catch (SQLException e) {
throw cquery.createPersistenceException(e);
}
@@ -27,6 +27,7 @@ class CQueryIteratorWithBuffer<T> implements QueryIterator<T> {
this.buffer = new ArrayList<T>(bufferSize);
}
@SuppressWarnings("unchecked")
public boolean hasNext() {
try {
if (buffer.isEmpty() && moreToLoad) {
@@ -35,7 +36,7 @@ class CQueryIteratorWithBuffer<T> implements QueryIterator<T> {
int i = -1;
while (moreToLoad && ++i < bufferSize) {
if (cquery.hasNextBean(true)) {
if (cquery.hasNextBean()) {
buffer.add((T)cquery.getLoadedBean());
} else {
moreToLoad = false;
@@ -2,7 +2,6 @@
package com.avaje.ebeaninternal.server.query;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map.Entry;
@@ -10,8 +9,8 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import com.avaje.ebean.bean.ObjectGraphNode;
import com.avaje.ebean.meta.MetaQueryPlanStatistic;
import com.avaje.ebean.meta.MetaQueryPlanOriginCount;
import com.avaje.ebean.meta.MetaQueryPlanStatistic;
import com.avaje.ebeaninternal.server.util.LongAdder;
/**
@@ -57,9 +57,6 @@ public class DefaultRelationalQueryEngine implements RelationalQueryEngine {
ResultSet rset = null;
PreparedStatement pstmt = null;
// flag indicating whether we need to close the resources...
boolean useBackgroundToContinueFetch = false;
String sql = query.getQuery();
BindParams bindParams = query.getBindParams();
@@ -170,17 +167,9 @@ public class DefaultRelationalQueryEngine implements RelationalQueryEngine {
}
}
if (!useBackgroundToContinueFetch) {
beanColl.setFinishedFetch(true);
}
if (request.isLogSummary()) {
long exeTime = System.currentTimeMillis() - startTime;
String msg = "SqlQuery rows[" + loadRowCount + "] time[" + exeTime + "] bind["
+ bindLog + "] finished[" + beanColl.isFinishedFetch() + "]";
String msg = "SqlQuery rows[" + loadRowCount + "] time[" + exeTime + "] bind[" + bindLog + "]";
t.logSummary(msg);
}
@@ -195,22 +184,20 @@ public class DefaultRelationalQueryEngine implements RelationalQueryEngine {
throw new PersistenceException(m, e);
} finally {
if (!useBackgroundToContinueFetch) {
try {
if (rset != null) {
rset.close();
}
} catch (SQLException e) {
logger.error(null, e);
try {
if (rset != null) {
rset.close();
}
try {
if (pstmt != null) {
pstmt.close();
}
} catch (SQLException e) {
logger.error(null, e);
} catch (SQLException e) {
logger.error(null, e);
}
try {
if (pstmt != null) {
pstmt.close();
}
}
} catch (SQLException e) {
logger.error(null, e);
}
}
}
@@ -140,11 +140,6 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
private List<Object> partialIds;
/**
* The rows after which the fetch continues in a bg thread.
*/
private int backgroundFetchAfter;
private int timeout = -1;
/**
@@ -434,7 +429,6 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
copy.additionalWhere = additionalWhere;
copy.additionalHaving = additionalHaving;
copy.distinct = distinct;
copy.backgroundFetchAfter = backgroundFetchAfter;
copy.timeout = timeout;
copy.mapKey = mapKey;
copy.id = id;
@@ -1089,15 +1083,6 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
return this;
}
public int getBackgroundFetchAfter() {
return backgroundFetchAfter;
}
public DefaultOrmQuery<T> setBackgroundFetchAfter(int backgroundFetchAfter) {
this.backgroundFetchAfter = backgroundFetchAfter;
return this;
}
public Object getId() {
return id;
}
@@ -1212,23 +1197,6 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
return whereExpressions;
}
/**
* Return true if using background fetching or a queryListener.
*/
public boolean createOwnTransaction() {
if (futureFetch){
// the future fetches have already created
// their own transaction
return false;
}
if (backgroundFetchAfter > 0) {
// run in own transaction as we can't know how long
// the background fetching will continue etc
return true;
}
return false;
}
public String getGeneratedSql() {
return generatedSql;
}
@@ -212,10 +212,6 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
return query.setMaxRows(maxRows);
}
public Query<T> setBackgroundFetchAfter(int backgroundFetchAfter) {
return query.setBackgroundFetchAfter(backgroundFetchAfter);
}
public Query<T> setMapKey(String mapKey) {
return query.setMapKey(mapKey);
}
@@ -127,10 +127,6 @@ public class FilterExpressionList<T> extends DefaultExpressionList<T> {
throw new PersistenceException(notAllowedMessage);
}
public Query<T> setBackgroundFetchAfter(int backgroundFetchAfter) {
return rootQuery.setBackgroundFetchAfter(backgroundFetchAfter);
}
public Query<T> setFirstRow(int firstRow) {
return rootQuery.setFirstRow(firstRow);
}