#566 - Refactor internals - SpiExpression, add prepareExpression() to merge queryAutoTuneHash() and queryPlanHash() - tidy up OrmQueryRequest

This commit is contained in:
Robin Bygrave
2016-02-16 17:07:56 +13:00
parent af554410fd
commit 69bf1758bc
6 changed files with 47 additions and 73 deletions
@@ -5,6 +5,9 @@ import com.avaje.ebean.bean.EntityBeanIntercept;
import com.avaje.ebean.bean.ObjectGraphNode;
import com.avaje.ebean.bean.PersistenceContext;
import com.avaje.ebeaninternal.server.core.OrmQueryRequest;
import com.avaje.ebeaninternal.server.querydefn.OrmQueryProperties;
import java.util.List;
/**
* Controls the loading of reference objects for a query instance.
@@ -23,16 +26,11 @@ public interface LoadContext {
void executeSecondaryQueries(OrmQueryRequest<?> parentRequest);
/**
* Register any secondary queries (+query or +lazy) with their
* appropriate LoadBeanContext or LoadManyContext.
* <p>
* This is so the LoadBeanContext or LoadManyContext use the
* defined query for +query and +lazy execution.
* </p>
* Register any secondary queries (+query or +lazy) with their appropriate LoadBeanContext or LoadManyContext.
*/
void registerSecondaryQueries(SpiQuery<?> query);
/**
void registerSecondaryQueries(List<OrmQueryProperties> queryJoins, List<OrmQueryProperties> lazyJoins);
/**
* Return the node for a given path which is used by AutoTune profiling.
*/
ObjectGraphNode getObjectGraphNode(String path);
@@ -289,16 +289,6 @@ public interface SpiQuery<T> extends Query<T> {
*/
void setBeanDescriptor(BeanDescriptor<?> desc);
/**
* Initialise/determine the joins required to support 'many' where clause predicates.
*/
boolean initManyWhereJoins();
/**
* Return true if one Many fetch join is allowed.
*/
boolean isAllowOneManyFetch();
/**
* Return the joins required to support predicates on the many properties.
*/
@@ -346,9 +336,9 @@ public interface SpiQuery<T> extends Query<T> {
void setLazyLoadManyPath(String lazyLoadManyPath);
/**
* Convert any many joins fetch joins to query joins.
* Convert joins as necessary to query joins etc.
*/
void convertManyFetchJoinsToQueryJoins(int queryBatch);
void convertJoins(int queryBatchSize);
/**
* Return the TransactionContext.
@@ -462,19 +462,10 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
return cqueryEngine.buildQuery(orm);
}
public CQueryEngine getQueryEngine() {
return cqueryEngine;
}
public ServerCacheManager getServerCacheManager() {
return serverCacheManager;
}
public void refreshMany(Object parentBean, String propertyName, Transaction t) {
beanLoader.refreshMany(checkEntityBean(parentBean), propertyName, t);
}
public void refreshMany(Object parentBean, String propertyName) {
beanLoader.refreshMany(checkEntityBean(parentBean), propertyName);
@@ -1073,17 +1064,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
query.setOrigin(createCallStack());
}
// determine extra joins required to support where clause
// predicates on *ToMany properties
if (query.initManyWhereJoins()) {
// we need a sql distinct now
query.setSqlDistinct(true);
}
query.convertManyFetchJoinsToQueryJoins(queryBatchSize);
OrmQueryRequest<T> request = new OrmQueryRequest<T>(this, queryEngine, query, desc, (SpiTransaction) t);
request.prepareQuery();
request.prepareQuery(queryBatchSize);
return request;
}
@@ -13,9 +13,9 @@ import com.avaje.ebean.event.BeanFindController;
import com.avaje.ebean.event.BeanQueryAdapter;
import com.avaje.ebean.event.BeanQueryRequest;
import com.avaje.ebeaninternal.api.BeanIdList;
import com.avaje.ebeaninternal.api.CQueryPlanKey;
import com.avaje.ebeaninternal.api.HashQuery;
import com.avaje.ebeaninternal.api.LoadContext;
import com.avaje.ebeaninternal.api.CQueryPlanKey;
import com.avaje.ebeaninternal.api.SpiEbeanServer;
import com.avaje.ebeaninternal.api.SpiQuery;
import com.avaje.ebeaninternal.api.SpiQuery.Type;
@@ -28,6 +28,7 @@ import com.avaje.ebeaninternal.server.deploy.DeployPropertyParserMap;
import com.avaje.ebeaninternal.server.loadcontext.DLoadContext;
import com.avaje.ebeaninternal.server.query.CQueryPlan;
import com.avaje.ebeaninternal.server.query.CancelableQuery;
import com.avaje.ebeaninternal.server.querydefn.OrmQueryProperties;
import com.avaje.ebeaninternal.server.transaction.DefaultPersistenceContext;
import javax.persistence.PersistenceException;
@@ -62,6 +63,10 @@ public final class OrmQueryRequest<T> extends BeanRequest implements BeanQueryRe
private CQueryPlanKey queryPlanKey;
private List<OrmQueryProperties> queryJoins;
private List<OrmQueryProperties> lazyJoins;
/**
* Create the InternalQueryRequest.
*/
@@ -143,8 +148,14 @@ public final class OrmQueryRequest<T> extends BeanRequest implements BeanQueryRe
/**
* Prepare the query and calculate the query plan key.
*/
public void prepareQuery() {
public void prepareQuery(int queryBatchSize) {
adapterPreQuery();
// determine extra joins required to support where clause predicates on *ToMany properties
query.convertJoins(queryBatchSize);
this.queryJoins = query.removeQueryJoins();
this.lazyJoins = query.removeLazyJoins();
this.queryPlanKey = query.prepare(this);
}
@@ -207,7 +218,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements BeanQueryRe
// initialise the persistenceContext and loadContext
this.persistenceContext = getPersistenceContext(query, transaction);
this.loadContext = new DLoadContext(this);
this.loadContext.registerSecondaryQueries(query);
this.loadContext.registerSecondaryQueries(queryJoins, lazyJoins);
}
/**
@@ -231,7 +242,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements BeanQueryRe
// determine the scope (from the query and then server)
PersistenceContextScope scope = ebeanServer.getPersistenceContextScope(query);
return (scope == PersistenceContextScope.QUERY) ? new DefaultPersistenceContext() : t.getPersistenceContext();
return (scope == PersistenceContextScope.QUERY) ? new DefaultPersistenceContext() : t.getPersistenceContext();
}
/**
@@ -321,7 +332,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements BeanQueryRe
*/
@SuppressWarnings("unchecked")
public Set<?> findSet() {
return (Set<T>)queryEngine.findMany(this);
return (Set<T>) queryEngine.findMany(this);
}
/**
@@ -119,8 +119,7 @@ public class DLoadContext implements LoadContext {
if (secQuery != null) {
for (int i = 0; i < secQuery.size(); i++) {
OrmQueryProperties properties = secQuery.get(i);
LoadSecondaryQuery load = getLoadSecondaryQuery(properties.getPath());
LoadSecondaryQuery load = getLoadSecondaryQuery(secQuery.get(i).getPath());
load.loadSecondaryQuery(parentRequest);
}
}
@@ -138,30 +137,19 @@ public class DLoadContext implements LoadContext {
}
/**
* Remove the +query and +lazy secondary queries and
* register them with their appropriate LoadBeanContext
* or LoadManyContext.
* <p>
* The parts of the secondary queries are removed and used
* by LoadBeanContext/LoadManyContext to build the appropriate
* queries.
* </p>
* Register the +query and +lazy secondary queries with their appropriate LoadBeanContext or LoadManyContext.
*/
public void registerSecondaryQueries(SpiQuery<?> query) {
public void registerSecondaryQueries(List<OrmQueryProperties> queryJoins, List<OrmQueryProperties> lazyJoins) {
secQuery = query.removeQueryJoins();
this.secQuery = queryJoins;
if (secQuery != null) {
for (int i = 0; i < secQuery.size(); i++) {
OrmQueryProperties props = secQuery.get(i);
registerSecondaryQuery(props);
registerSecondaryQuery(secQuery.get(i));
}
}
List<OrmQueryProperties> lazyQueries = query.removeLazyJoins();
if (lazyQueries != null) {
for (int i = 0; i < lazyQueries.size(); i++) {
OrmQueryProperties lazyProps = lazyQueries.get(i);
registerSecondaryQuery(lazyProps);
if (lazyJoins != null) {
for (int i = 0; i < lazyJoins.size(); i++) {
registerSecondaryQuery(lazyJoins.get(i));
}
}
}
@@ -172,14 +160,12 @@ public class DLoadContext implements LoadContext {
*/
private void registerSecondaryQuery(OrmQueryProperties props) {
String propName = props.getPath();
ElPropertyValue elGetValue = rootDescriptor.getElGetValue(propName);
ElPropertyValue elGetValue = rootDescriptor.getElGetValue(props.getPath());
boolean many = elGetValue.getBeanProperty().containsMany();
registerSecondaryNode(many, props);
}
public ObjectGraphNode getObjectGraphNode(String path) {
ObjectGraphNode node = nodePathMap.get(path);
@@ -378,12 +378,14 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
/**
* Return true if the where expressions contains a many property.
*/
public boolean initManyWhereJoins() {
private void initManyWhereJoins() {
manyWhereJoins = new ManyWhereJoins();
if (whereExpressions != null) {
whereExpressions.containsMany(beanDescriptor, manyWhereJoins);
}
return !manyWhereJoins.isEmpty();
if (!manyWhereJoins.isEmpty()) {
setSqlDistinct(true);
}
}
public ManyWhereJoins getManyWhereJoins() {
@@ -440,8 +442,7 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
this.lazyLoadManyPath = lazyLoadManyPath;
}
@Override
public boolean isAllowOneManyFetch() {
private boolean isAllowOneManyFetch() {
if (Mode.LAZYLOAD_MANY.equals(getMode())) {
return false;
@@ -453,10 +454,16 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
return true;
}
@Override
public void convertJoins(int queryBatchSize) {
initManyWhereJoins();
convertManyFetchJoinsToQueryJoins(queryBatchSize);
}
/**
* Convert any many joins fetch joins to query joins.
*/
public void convertManyFetchJoinsToQueryJoins(int queryBatch) {
private void convertManyFetchJoinsToQueryJoins(int queryBatch) {
boolean allowOne = isAllowOneManyFetch();
detail.convertManyFetchJoinsToQueryJoins(beanDescriptor, lazyLoadManyPath, allowOne, queryBatch);
}