Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.avaje.ebeaninternal.server.querydefn.DefaultOrmQuery Maven / Gradle / Ivy
package com.avaje.ebeaninternal.server.querydefn;
import com.avaje.ebean.*;
import com.avaje.ebean.OrderBy.Property;
import com.avaje.ebean.bean.CallStack;
import com.avaje.ebean.bean.ObjectGraphNode;
import com.avaje.ebean.bean.ObjectGraphOrigin;
import com.avaje.ebean.bean.PersistenceContext;
import com.avaje.ebean.event.BeanQueryRequest;
import com.avaje.ebean.event.readaudit.ReadEvent;
import com.avaje.ebean.plugin.BeanType;
import com.avaje.ebeaninternal.api.BindParams;
import com.avaje.ebeaninternal.api.CQueryPlanKey;
import com.avaje.ebeaninternal.api.HashQuery;
import com.avaje.ebeaninternal.api.ManyWhereJoins;
import com.avaje.ebeaninternal.api.SpiExpression;
import com.avaje.ebeaninternal.api.SpiExpressionList;
import com.avaje.ebeaninternal.api.SpiExpressionValidation;
import com.avaje.ebeaninternal.api.SpiNamedParam;
import com.avaje.ebeaninternal.api.SpiQuery;
import com.avaje.ebeaninternal.api.SpiQuerySecondary;
import com.avaje.ebeaninternal.server.autotune.ProfilingListener;
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
import com.avaje.ebeaninternal.server.deploy.TableJoin;
import com.avaje.ebeaninternal.server.expression.DefaultExpressionList;
import com.avaje.ebeaninternal.server.expression.SimpleExpression;
import com.avaje.ebeaninternal.server.query.CancelableQuery;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Default implementation of an Object Relational query.
*/
public class DefaultOrmQuery implements SpiQuery {
public static final String DEFAULT_QUERY_NAME = "default";
private final Class beanType;
private final BeanDescriptor beanDescriptor;
private final EbeanServer server;
private final ExpressionFactory expressionFactory;
/**
* For lazy loading of ManyToMany we need to add a join to the intersection table. This is that
* join to the intersection table.
*/
private TableJoin includeTableJoin;
private ProfilingListener profilingListener;
private boolean cancelled;
private CancelableQuery cancelableQuery;
private Type type;
private Mode mode = Mode.NORMAL;
/**
* Holds query in structured form.
*/
private OrmQueryDetail detail;
private int maxRows;
private int firstRow;
/**
* Set to true to disable lazy loading on the object graph returned.
*/
private boolean disableLazyLoading;
/**
* Lazy loading batch size (can override server wide default).
*/
private int lazyLoadBatchSize;
private OrderBy orderBy;
private String loadMode;
private String loadDescription;
private String generatedSql;
private String lazyLoadProperty;
private String lazyLoadManyPath;
/**
* Set to true by a user wanting a DISTINCT query (id property must be excluded).
*/
private boolean distinct;
/**
* Set to true internally by Ebean when it needs the DISTINCT keyword added to the query (id
* property still expected).
*/
private boolean sqlDistinct;
/**
* Set to true if this is a future fetch using background threads.
*/
private boolean futureFetch;
/**
* Only used for read auditing with findFutureList() query.
*/
private ReadEvent futureFetchAudit;
private List partialIds;
private int timeout;
/**
* The property used to get the key value for a Map.
*/
private String mapKey;
/**
* Used for find by id type query.
*/
private Object id;
private Map namedParams;
/**
* Bind parameters when using the query language.
*/
private BindParams bindParams;
private DefaultExpressionList textExpressions;
private DefaultExpressionList whereExpressions;
private DefaultExpressionList havingExpressions;
private boolean asOfBaseTable;
private int asOfTableCount;
/**
* Set for flashback style 'as of' query.
*/
private Timestamp asOf;
private TemporalMode temporalMode = TemporalMode.CURRENT;
private Timestamp versionsStart;
private Timestamp versionsEnd;
private List softDeletePredicates;
private boolean disableReadAudit;
private int bufferFetchSizeHint;
private boolean usageProfiling = true;
private boolean loadBeanCache;
private boolean excludeBeanCache;
private Boolean useQueryCache;
private Boolean readOnly;
private PersistenceContextScope persistenceContextScope;
/**
* Allow for explicit on off or null for default.
*/
private Boolean autoTune;
/**
* Allow to fetch a record "for update" which should lock it on read
*/
private boolean forUpdate;
/**
* Set to true if this query has been tuned by autoTune.
*/
private boolean autoTuned;
private boolean logSecondaryQuery;
/**
* Root table alias. For {@link Query#alias(String)} command.
*/
private String rootTableAlias;
/**
* The node of the bean or collection that fired lazy loading. Not null if profiling is on and
* this query is for lazy loading. Used to hook back a lazy loading query to the "original" query
* point.
*/
private ObjectGraphNode parentNode;
private BeanPropertyAssocMany> lazyLoadForParentsProperty;
/**
* Hash of final query after AutoTune tuning.
*/
private CQueryPlanKey queryPlanKey;
private PersistenceContext persistenceContext;
private ManyWhereJoins manyWhereJoins;
private RawSql rawSql;
private boolean useDocStore;
private OrmUpdateProperties updateProperties;
public DefaultOrmQuery(BeanDescriptor desc, EbeanServer server, ExpressionFactory expressionFactory) {
this.beanDescriptor = desc;
this.beanType = desc.getBeanType();
this.server = server;
this.expressionFactory = expressionFactory;
this.detail = new OrmQueryDetail();
}
@Override
public BeanDescriptor getBeanDescriptor() {
return beanDescriptor;
}
@Override
public void checkIdEqualTo() {
if (id == null && whereExpressions != null) {
id = whereExpressions.idEqualTo(beanDescriptor.getIdName());
if (id != null) {
whereExpressions = null;
}
}
}
@Override
public boolean isAutoTunable() {
return beanDescriptor.isAutoTunable();
}
@Override
public Query setUseDocStore(boolean useDocStore) {
this.useDocStore = useDocStore;
return this;
}
@Override
public boolean isUseDocStore() {
return useDocStore;
}
@Override
public Query apply(FetchPath fetchPath) {
fetchPath.apply(this);
return this;
}
@Override
public void addSoftDeletePredicate(String softDeletePredicate) {
if (softDeletePredicates == null) {
softDeletePredicates = new ArrayList();
}
softDeletePredicates.add(softDeletePredicate);
}
@Override
public List getSoftDeletePredicates() {
return softDeletePredicates;
}
public boolean isAsOfBaseTable() {
return asOfBaseTable;
}
public void setAsOfBaseTable() {
this.asOfBaseTable = true;
}
@Override
public void incrementAsOfTableCount() {
asOfTableCount++;
}
@Override
public int getAsOfTableCount() {
return asOfTableCount;
}
@Override
public Timestamp getAsOf() {
return asOf;
}
@Override
public DefaultOrmQuery asOf(Timestamp asOfDateTime) {
this.temporalMode = (asOfDateTime != null) ? TemporalMode.AS_OF : TemporalMode.CURRENT;
this.asOf = asOfDateTime;
return this;
}
@Override
public DefaultOrmQuery asDraft() {
this.temporalMode = TemporalMode.DRAFT;
return this;
}
@Override
public Query setIncludeSoftDeletes() {
this.temporalMode = TemporalMode.SOFT_DELETED;
return this;
}
@Override
public RawSql getRawSql() {
return rawSql;
}
@Override
public DefaultOrmQuery setRawSql(RawSql rawSql) {
this.rawSql = rawSql;
return this;
}
@Override
public int getLazyLoadBatchSize() {
return lazyLoadBatchSize;
}
@Override
public Query setLazyLoadBatchSize(int lazyLoadBatchSize) {
this.lazyLoadBatchSize = lazyLoadBatchSize;
return this;
}
@Override
public String getLazyLoadProperty() {
return lazyLoadProperty;
}
@Override
public void setLazyLoadProperty(String lazyLoadProperty) {
this.lazyLoadProperty = lazyLoadProperty;
}
@Override
public ExpressionFactory getExpressionFactory() {
return expressionFactory;
}
private void createExtraJoinsToSupportManyWhereClause() {
manyWhereJoins = new ManyWhereJoins();
if (whereExpressions != null) {
whereExpressions.containsMany(beanDescriptor, manyWhereJoins);
}
if (!manyWhereJoins.isEmpty()) {
setSqlDistinct(true);
}
}
/**
* Return the extra joins required to support the where clause for 'Many' properties.
*/
@Override
public ManyWhereJoins getManyWhereJoins() {
return manyWhereJoins;
}
/**
* Return true if select all properties was used to ensure the property invoking a lazy load was
* included in the query.
*/
@Override
public boolean selectAllForLazyLoadProperty() {
if (lazyLoadProperty != null) {
if (!detail.containsProperty(lazyLoadProperty)) {
detail.select("*");
return true;
}
}
return false;
}
protected List removeQueryJoins() {
List queryJoins = detail.removeSecondaryQueries();
if (queryJoins != null) {
if (orderBy != null) {
// remove any orderBy properties that relate to
// paths of the secondary queries
for (int i = 0; i < queryJoins.size(); i++) {
OrmQueryProperties joinPath = queryJoins.get(i);
// loop through the orderBy properties and
// move any ones related to the query join
List properties = orderBy.getProperties();
Iterator it = properties.iterator();
while (it.hasNext()) {
OrderBy.Property property = it.next();
if (property.getProperty().startsWith(joinPath.getPath())) {
// remove this orderBy segment and
// add it to the secondary join
it.remove();
joinPath.addSecJoinOrderProperty(property);
}
}
}
}
}
return queryJoins;
}
protected List removeLazyJoins() {
return detail.removeSecondaryLazyQueries();
}
@Override
public void setLazyLoadManyPath(String lazyLoadManyPath) {
this.lazyLoadManyPath = lazyLoadManyPath;
}
@Override
public SpiQuerySecondary convertJoins() {
if (!useDocStore) {
createExtraJoinsToSupportManyWhereClause();
}
markQueryJoins();
return new OrmQuerySecondary(removeQueryJoins(), removeLazyJoins());
}
/**
* Limit the number of fetch joins to Many properties, mark as query joins as needed.
*/
private void markQueryJoins() {
detail.markQueryJoins(beanDescriptor, lazyLoadManyPath, isAllowOneManyFetch());
}
private boolean isAllowOneManyFetch() {
if (Mode.LAZYLOAD_MANY.equals(getMode())) {
return false;
} else if (hasMaxRowsOrFirstRow() && !isRawSql()) {
return false;
}
return true;
}
protected void setOrmQueryDetail(OrmQueryDetail detail) {
this.detail = detail;
}
@Override
public void setDefaultSelectClause() {
detail.setDefaultSelectClause(beanDescriptor);
}
@Override
public void setDetail(OrmQueryDetail detail) {
this.detail = detail;
}
@Override
public boolean tuneFetchProperties(OrmQueryDetail tunedDetail) {
return detail.tuneFetchProperties(tunedDetail);
}
@Override
public OrmQueryDetail getDetail() {
return detail;
}
@Override
public ExpressionList filterMany(String prop) {
OrmQueryProperties chunk = detail.getChunk(prop, true);
return chunk.filterMany(this);
}
@Override
public void setFilterMany(String prop, ExpressionList> filterMany) {
if (filterMany != null) {
OrmQueryProperties chunk = detail.getChunk(prop, true);
chunk.setFilterMany((SpiExpressionList>) filterMany);
}
}
@Override
public void prepareDocNested() {
if (textExpressions != null) {
textExpressions.prepareDocNested(beanDescriptor);
}
if (whereExpressions != null) {
whereExpressions.prepareDocNested(beanDescriptor);
}
}
/**
* Setup to be a delete query.
*/
@Override
public void setDelete() {
// unset any paging and select on the id in the case where the query
// includes joins and we use - delete ... where id in (...)
maxRows = 0;
firstRow = 0;
forUpdate = false;
rootTableAlias = "${RTA}"; // alias we remove later
setSelectId();
}
/**
* Set the select clause to select the Id property.
*/
@Override
public void setSelectId() {
// clear select and fetch joins..
detail.clear();
select(beanDescriptor.getIdBinder().getIdProperty());
}
@Override
public NaturalKeyBindParam getNaturalKeyBindParam() {
NaturalKeyBindParam namedBind = null;
if (bindParams != null) {
namedBind = bindParams.getNaturalKeyBindParam();
if (namedBind == null) {
return null;
}
}
if (whereExpressions != null) {
List exprList = whereExpressions.internalList();
if (exprList.size() > 1) {
return null;
} else if (exprList.isEmpty()) {
return namedBind;
} else {
if (namedBind != null) {
return null;
}
SpiExpression se = exprList.get(0);
if (se instanceof SimpleExpression) {
SimpleExpression e = (SimpleExpression) se;
if (e.isOpEquals()) {
return new NaturalKeyBindParam(e.getPropName(), e.getValue());
}
}
}
}
return null;
}
@Override
public DefaultOrmQuery copy() {
return copy(server);
}
@Override
public DefaultOrmQuery copy(EbeanServer server) {
DefaultOrmQuery copy = new DefaultOrmQuery(beanDescriptor, server, expressionFactory);
copy.includeTableJoin = includeTableJoin;
copy.profilingListener = profilingListener;
// copy.query = query;
copy.rootTableAlias = rootTableAlias;
copy.distinct = distinct;
copy.sqlDistinct = sqlDistinct;
copy.timeout = timeout;
copy.mapKey = mapKey;
copy.id = id;
copy.loadBeanCache = loadBeanCache;
copy.excludeBeanCache = excludeBeanCache;
copy.useQueryCache = useQueryCache;
copy.readOnly = readOnly;
if (detail != null) {
copy.detail = detail.copy();
}
copy.temporalMode = temporalMode;
copy.firstRow = firstRow;
copy.maxRows = maxRows;
if (orderBy != null) {
copy.orderBy = orderBy.copy();
}
if (bindParams != null) {
copy.bindParams = bindParams.copy();
}
if (whereExpressions != null) {
copy.whereExpressions = whereExpressions.copy(copy);
}
if (havingExpressions != null) {
copy.havingExpressions = havingExpressions.copy(copy);
}
copy.persistenceContextScope = persistenceContextScope;
copy.usageProfiling = usageProfiling;
copy.autoTune = autoTune;
copy.parentNode = parentNode;
copy.forUpdate = forUpdate;
copy.rawSql = rawSql;
return copy;
}
@Override
public Query setPersistenceContextScope(PersistenceContextScope scope) {
this.persistenceContextScope = scope;
return this;
}
@Override
public PersistenceContextScope getPersistenceContextScope() {
return persistenceContextScope;
}
@Override
public Type getType() {
return type;
}
@Override
public void setType(Type type) {
this.type = type;
}
@Override
public String getLoadDescription() {
return loadDescription;
}
@Override
public String getLoadMode() {
return loadMode;
}
@Override
public void setLoadDescription(String loadMode, String loadDescription) {
this.loadMode = loadMode;
this.loadDescription = loadDescription;
}
/**
* Return the TransactionContext.
*
* If no TransactionContext is present on the query then the TransactionContext from the
* Transaction is used (transaction scoped persistence context).
*
*/
@Override
public PersistenceContext getPersistenceContext() {
return persistenceContext;
}
/**
* Set an explicit TransactionContext (typically for a refresh query).
*
* If no TransactionContext is present on the query then the TransactionContext from the
* Transaction is used (transaction scoped persistence context).
*
*/
@Override
public void setPersistenceContext(PersistenceContext persistenceContext) {
this.persistenceContext = persistenceContext;
}
@Override
public void setLazyLoadForParents(BeanPropertyAssocMany> many) {
this.lazyLoadForParentsProperty = many;
}
@Override
public BeanPropertyAssocMany> getLazyLoadMany() {
return lazyLoadForParentsProperty;
}
/**
* Return true if the query detail has neither select or joins specified.
*/
@Override
public boolean isDetailEmpty() {
return detail.isEmpty();
}
@Override
public boolean isAutoTuned() {
return autoTuned;
}
@Override
public void setAutoTuned(boolean autoTuned) {
this.autoTuned = autoTuned;
}
@Override
public Boolean isAutoTune() {
return autoTune;
}
@Override
public boolean isForUpdate() {
return forUpdate;
}
@Override
public void setDefaultRawSqlIfRequired() {
if (beanDescriptor.isRawSqlBased() && rawSql == null) {
rawSql = beanDescriptor.getNamedRawSql(DEFAULT_QUERY_NAME);
}
}
@Override
public DefaultOrmQuery setAutoTune(boolean autoTune) {
this.autoTune = autoTune;
return this;
}
@Override
public DefaultOrmQuery setForUpdate(boolean forUpdate) {
this.forUpdate = forUpdate;
return this;
}
@Override
public ProfilingListener getProfilingListener() {
return profilingListener;
}
@Override
public void setProfilingListener(ProfilingListener profilingListener) {
this.profilingListener = profilingListener;
}
@Override
public Mode getMode() {
return mode;
}
@Override
public TemporalMode getTemporalMode() {
return temporalMode;
}
@Override
public boolean isAsOfQuery() {
return asOf != null;
}
@Override
public boolean isAsDraft() {
return TemporalMode.DRAFT == temporalMode;
}
@Override
public boolean isIncludeSoftDeletes() {
return TemporalMode.SOFT_DELETED == temporalMode;
}
@Override
public void setMode(Mode mode) {
this.mode = mode;
}
@Override
public boolean isUsageProfiling() {
return usageProfiling;
}
@Override
public void setUsageProfiling(boolean usageProfiling) {
this.usageProfiling = usageProfiling;
}
@Override
public void setLogSecondaryQuery(boolean logSecondaryQuery) {
this.logSecondaryQuery = logSecondaryQuery;
}
@Override
public boolean isLogSecondaryQuery() {
return logSecondaryQuery;
}
private List> loggedSecondaryQueries;
@Override
public List> getLoggedSecondaryQueries() {
return loggedSecondaryQueries;
}
@Override
public void logSecondaryQuery(SpiQuery> query) {
if (loggedSecondaryQueries == null) {
loggedSecondaryQueries = new ArrayList>();
}
loggedSecondaryQueries.add(query);
}
@Override
public void setParentNode(ObjectGraphNode parentNode) {
this.parentNode = parentNode;
}
@Override
public ObjectGraphNode getParentNode() {
return parentNode;
}
@Override
public ObjectGraphNode setOrigin(CallStack callStack) {
// create a 'origin' which links this query to the profiling information
ObjectGraphOrigin o = new ObjectGraphOrigin(calculateOriginQueryHash(), callStack, beanType.getName());
parentNode = new ObjectGraphNode(o, null);
return parentNode;
}
/**
* Calculate a hash for use in determining the ObjectGraphOrigin.
*
* This should be quite a stable hash as most uniqueness is determined by the CallStack, so we
* only use the bean type and overall query type.
*
*
* This stable hash allows the query to be changed (joins added etc) without losing the already
* collected usage profiling.
*
*/
private int calculateOriginQueryHash() {
int hc = beanType.getName().hashCode();
hc = hc * 31 + (type == null ? 0 : type.ordinal());
return hc;
}
/**
* Calculate the query hash for either AutoTune query tuning or Query Plan caching.
*/
CQueryPlanKey createQueryPlanKey() {
queryPlanKey = new OrmQueryPlanKey(includeTableJoin, type, detail, maxRows, firstRow,
disableLazyLoading, orderBy,
distinct, sqlDistinct, mapKey, id, bindParams, whereExpressions, havingExpressions,
temporalMode, forUpdate, rootTableAlias, rawSql, updateProperties);
return queryPlanKey;
}
/**
* Prepare the query which prepares any expressions (sub-query expressions etc) and calculates the query plan key.
*/
@Override
public CQueryPlanKey prepare(BeanQueryRequest> request) {
prepareExpressions(request);
queryPlanKey = createQueryPlanKey();
return queryPlanKey;
}
/**
* Prepare the expressions (compile sub-queries etc).
*/
private void prepareExpressions(BeanQueryRequest> request) {
if (whereExpressions != null) {
whereExpressions.prepareExpression(request);
}
if (havingExpressions != null) {
havingExpressions.prepareExpression(request);
}
}
/**
* Calculate a hash based on the bind values used in the query.
*
* Used with queryPlanHash() to get a unique hash for a query.
*
*/
@Override
public int queryBindHash() {
int hc = (id == null ? 0 : id.hashCode());
hc = hc * 31 + (whereExpressions == null ? 0 : whereExpressions.queryBindHash());
hc = hc * 31 + (havingExpressions == null ? 0 : havingExpressions.queryBindHash());
hc = hc * 31 + (bindParams == null ? 0 : bindParams.queryBindHash());
hc = hc * 31 + (asOf == null ? 0 : asOf.hashCode());
hc = hc * 31 + (versionsStart == null ? 0 : versionsStart.hashCode());
hc = hc * 31 + (versionsEnd == null ? 0 : versionsEnd.hashCode());
return hc;
}
/**
* Return a hash that includes the query plan and bind values.
*
* This hash can be used to identify if we have executed the exact same query (including bind
* values) before.
*
*/
@Override
public HashQuery queryHash() {
// calculateQueryPlanHash is called just after potential AutoTune tuning
// so queryPlanHash is calculated well before this method is called
int hc = queryBindHash();
return new HashQuery(queryPlanKey, hc);
}
@Override
public boolean isRawSql() {
return rawSql != null;
}
/**
* Return the timeout.
*/
@Override
public int getTimeout() {
return timeout;
}
@Override
public boolean hasMaxRowsOrFirstRow() {
return maxRows > 0 || firstRow > 0;
}
@Override
public boolean isVersionsBetween() {
return versionsStart != null;
}
@Override
public Timestamp getVersionStart() {
return versionsStart;
}
@Override
public Timestamp getVersionEnd() {
return versionsEnd;
}
@Override
public Boolean isReadOnly() {
return readOnly;
}
@Override
public DefaultOrmQuery setReadOnly(boolean readOnly) {
this.readOnly = readOnly;
return this;
}
public boolean isExcludeBeanCache() {
// not using L2 cache for asDraft() query
return excludeBeanCache || isAsDraft() ;
}
@Override
public boolean isUseBeanCache() {
return !isExcludeBeanCache() && beanDescriptor.isBeanCaching();
}
@Override
public boolean isUseQueryCache() {
// not using L2 cache for asDraft() query
return !isAsDraft() && Boolean.TRUE.equals(useQueryCache);
}
@Override
public DefaultOrmQuery setUseCache(boolean useCache) {
this.excludeBeanCache = !useCache;
return this;
}
@Override
public DefaultOrmQuery setUseQueryCache(boolean useQueryCache) {
this.useQueryCache = useQueryCache;
return this;
}
@Override
public boolean isLoadBeanCache() {
// not using L2 cache for asDraft() query
return !isAsDraft() && loadBeanCache;
}
@Override
public DefaultOrmQuery setLoadBeanCache(boolean loadBeanCache) {
this.loadBeanCache = loadBeanCache;
return this;
}
@Override
public DefaultOrmQuery setTimeout(int secs) {
this.timeout = secs;
return this;
}
@Override
public DefaultOrmQuery select(String columns) {
detail.select(columns);
return this;
}
@Override
public DefaultOrmQuery fetch(String property) {
return fetch(property, null, null);
}
@Override
public DefaultOrmQuery fetch(String property, FetchConfig joinConfig) {
return fetch(property, null, joinConfig);
}
@Override
public DefaultOrmQuery fetch(String property, String columns) {
return fetch(property, columns, null);
}
@Override
public DefaultOrmQuery fetch(String property, String columns, FetchConfig config) {
detail.fetch(property, columns, config);
return this;
}
@Override
public int delete() {
return server.delete(this, null);
}
@Override
public int update() {
return server.update(this, null);
}
@Override
public List findIds() {
// a copy of this query is made in the server
// as the query needs to modified (so we modify
// the copy rather than this query instance)
return server.findIds(this, null);
}
@Override
public int findCount() {
// a copy of this query is made in the server
// as the query needs to modified (so we modify
// the copy rather than this query instance)
return server.findCount(this, null);
}
@Override
public int findRowCount() {
return findCount();
}
@Override
public void findEachWhile(QueryEachWhileConsumer consumer) {
server.findEachWhile(this, consumer, null);
}
@Override
public void findEach(QueryEachConsumer consumer) {
server.findEach(this, consumer, null);
}
@Override
public List> findVersions() {
this.temporalMode = TemporalMode.VERSIONS;
return server.findVersions(this, null);
}
@Override
public List> findVersionsBetween(Timestamp start, Timestamp end) {
if (start == null || end == null) {
throw new IllegalArgumentException("start and end must not be null");
}
this.temporalMode = TemporalMode.VERSIONS;
this.versionsStart = start;
this.versionsEnd = end;
return server.findVersions(this, null);
}
@Override
public List findList() {
return server.findList(this, null);
}
@Override
public Set findSet() {
return server.findSet(this, null);
}
@Override
public Map, T> findMap() {
return server.findMap(this, null);
}
@Override
@SuppressWarnings("unchecked")
public Map findMap(String keyProperty, Class keyType) {
setMapKey(keyProperty);
return (Map) findMap();
}
@Override
public T findUnique() {
return server.findUnique(this, null);
}
@Override
public FutureIds findFutureIds() {
return server.findFutureIds(this, null);
}
@Override
public FutureList findFutureList() {
return server.findFutureList(this, null);
}
@Override
public FutureRowCount findFutureCount() {
return server.findFutureCount(this, null);
}
@Override
public FutureRowCount findFutureRowCount() {
return findFutureCount();
}
@Override
public PagedList findPagedList() {
return server.findPagedList(this, null);
}
/**
* Set an ordered bind parameter according to its position. Note that the position starts at 1 to
* be consistent with JDBC PreparedStatement. You need to set a parameter value for each ? you
* have in the query.
*/
@Override
public DefaultOrmQuery setParameter(int position, Object value) {
if (bindParams == null) {
bindParams = new BindParams();
}
bindParams.setParameter(position, value);
return this;
}
/**
* Set a named bind parameter. Named parameters have a colon to prefix the name.
*/
@Override
public DefaultOrmQuery setParameter(String name, Object value) {
if (namedParams != null) {
ONamedParam param = namedParams.get(name);
if (param != null) {
param.setValue(value);
return this;
}
}
if (bindParams == null) {
bindParams = new BindParams();
}
bindParams.setParameter(name, value);
return this;
}
@Override
public OrderBy getOrderBy() {
return orderBy;
}
@Override
public OrderBy orderBy() {
return order();
}
@Override
public OrderBy order() {
if (orderBy == null) {
orderBy = new OrderBy(this, null);
}
return orderBy;
}
@Override
public DefaultOrmQuery orderBy(String orderByClause) {
return order(orderByClause);
}
@Override
public DefaultOrmQuery order(String orderByClause) {
if (orderByClause == null || orderByClause.trim().isEmpty()) {
this.orderBy = null;
} else {
this.orderBy = new OrderBy(this, orderByClause);
}
return this;
}
@Override
public DefaultOrmQuery setOrderBy(OrderBy orderBy) {
return setOrder(orderBy);
}
@Override
public DefaultOrmQuery setOrder(OrderBy orderBy) {
this.orderBy = orderBy;
if (orderBy != null) {
orderBy.setQuery(this);
}
return this;
}
/**
* return true if user specified to use SQL DISTINCT (effectively excludes id property).
*/
@Override
public boolean isDistinct() {
return distinct;
}
/**
* Internally set to use SQL DISTINCT on the query but still have id property included.
*/
@Override
public DefaultOrmQuery setDistinct(boolean distinct) {
this.distinct = distinct;
return this;
}
/**
* Return true if this query uses SQL DISTINCT either explicitly by the user or internally defined
* by ebean.
*/
@Override
public boolean isDistinctQuery() {
return distinct || sqlDistinct;
}
/**
* Internally set to use SQL DISTINCT on the query but still have id property included.
*/
@Override
public void setSqlDistinct(boolean sqlDistinct) {
this.sqlDistinct = sqlDistinct;
}
@Override
public Class getBeanType() {
return beanType;
}
public String toString() {
return "Query [" + whereExpressions + "]";
}
@Override
public TableJoin getIncludeTableJoin() {
return includeTableJoin;
}
@Override
public void setIncludeTableJoin(TableJoin includeTableJoin) {
this.includeTableJoin = includeTableJoin;
}
@Override
public Query setDisableLazyLoading(boolean disableLazyLoading) {
this.disableLazyLoading = disableLazyLoading;
return this;
}
@Override
public boolean isDisableLazyLoading() {
return disableLazyLoading;
}
@Override
public int getFirstRow() {
return firstRow;
}
@Override
public DefaultOrmQuery setFirstRow(int firstRow) {
this.firstRow = firstRow;
return this;
}
@Override
public int getMaxRows() {
return maxRows;
}
@Override
public DefaultOrmQuery setMaxRows(int maxRows) {
this.maxRows = maxRows;
return this;
}
@Override
public String getMapKey() {
return mapKey;
}
@Override
public DefaultOrmQuery setMapKey(String mapKey) {
this.mapKey = mapKey;
return this;
}
@Override
public Object getId() {
return id;
}
@Override
public DefaultOrmQuery setId(Object id) {
if (id == null) {
throw new NullPointerException("The id is null");
}
this.id = id;
return this;
}
@Override
public BindParams getBindParams() {
return bindParams;
}
@Override
public DefaultOrmQuery where(Expression expression) {
where().add(expression);
return this;
}
@Override
public ExpressionList text() {
if (textExpressions == null) {
useDocStore = true;
textExpressions = new DefaultExpressionList(this);
}
return textExpressions;
}
@Override
public ExpressionList where() {
if (whereExpressions == null) {
whereExpressions = new DefaultExpressionList(this, null);
}
return whereExpressions;
}
@Override
public void simplifyExpressions() {
if (whereExpressions != null) {
whereExpressions.simplify();
}
}
@Override
public DefaultOrmQuery having(Expression expression) {
having().add(expression);
return this;
}
@Override
public ExpressionList having() {
if (havingExpressions == null) {
havingExpressions = new DefaultExpressionList(this, null);
}
return havingExpressions;
}
@Override
public SpiExpressionList getHavingExpressions() {
return havingExpressions;
}
@Override
public SpiExpressionList getWhereExpressions() {
return whereExpressions;
}
@Override
public SpiExpressionList getTextExpression() {
return textExpressions;
}
@Override
public String getGeneratedSql() {
return generatedSql;
}
@Override
public void setGeneratedSql(String generatedSql) {
this.generatedSql = generatedSql;
}
@Override
public void checkNamedParameters() {
if (namedParams != null) {
Collection values = namedParams.values();
for (ONamedParam value : values) {
value.checkValueSet();
}
}
}
@Override
public SpiNamedParam createNamedParameter(String name) {
if (namedParams == null) {
namedParams = new HashMap();
}
ONamedParam param = namedParams.get(name);
if (param == null) {
param = new ONamedParam(name);
namedParams.put(name, param);
}
return param;
}
@Override
public void setDefaultFetchBuffer(int fetchSize) {
if (bufferFetchSizeHint == 0) {
bufferFetchSizeHint = fetchSize;
}
}
@Override
public Query setBufferFetchSizeHint(int bufferFetchSizeHint) {
this.bufferFetchSizeHint = bufferFetchSizeHint;
return this;
}
@Override
public int getBufferFetchSizeHint() {
return bufferFetchSizeHint;
}
@Override
public Query setDisableReadAuditing() {
this.disableReadAudit = true;
return this;
}
@Override
public boolean isDisableReadAudit() {
return disableReadAudit;
}
@Override
public List getIdList() {
return partialIds;
}
@Override
public void setIdList(List partialIds) {
this.partialIds = partialIds;
}
@Override
public boolean isFutureFetch() {
return futureFetch;
}
@Override
public void setFutureFetch(boolean backgroundFetch) {
this.futureFetch = backgroundFetch;
}
@Override
public void setFutureFetchAudit(ReadEvent event) {
this.futureFetchAudit = event;
}
@Override
public ReadEvent getFutureFetchAudit() {
return futureFetchAudit;
}
@Override
public void setCancelableQuery(CancelableQuery cancelableQuery) {
synchronized (this) {
this.cancelableQuery = cancelableQuery;
}
}
@Override
public Query alias(String alias) {
this.rootTableAlias = alias;
return this;
}
@Override
public String getAlias() {
return rootTableAlias;
}
@Override
public void cancel() {
synchronized (this) {
cancelled = true;
if (cancelableQuery != null) {
cancelableQuery.cancel();
}
}
}
@Override
public boolean isCancelled() {
synchronized (this) {
return cancelled;
}
}
@Override
public Set validate() {
return server.validateQuery(this);
}
/**
* Validate all the expression properties/paths given the bean descriptor.
*/
@Override
public Set validate(BeanType desc) {
SpiExpressionValidation validation = new SpiExpressionValidation(desc);
if (whereExpressions != null) {
whereExpressions.validate(validation);
}
if (havingExpressions != null) {
havingExpressions.validate(validation);
}
if (orderBy != null) {
for (Property property : orderBy.getProperties()) {
validation.validate(property.getProperty());
}
}
return validation.getUnknownProperties();
}
public void setUpdateProperties(OrmUpdateProperties updateProperties) {
this.updateProperties = updateProperties;
}
@Override
public OrmUpdateProperties getUpdateProperties() {
return updateProperties;
}
}