mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Fix for #87 - v4 - Remove Query setBackgroundFetchAfter() feature
This commit is contained in:
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
+13
-26
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user