diff --git a/src/main/java/com/avaje/ebeaninternal/api/LoadContext.java b/src/main/java/com/avaje/ebeaninternal/api/LoadContext.java index 3a29927e2..82fd3c8c7 100644 --- a/src/main/java/com/avaje/ebeaninternal/api/LoadContext.java +++ b/src/main/java/com/avaje/ebeaninternal/api/LoadContext.java @@ -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. - *

- * This is so the LoadBeanContext or LoadManyContext use the - * defined query for +query and +lazy execution. - *

+ * Register any secondary queries (+query or +lazy) with their appropriate LoadBeanContext or LoadManyContext. */ - void registerSecondaryQueries(SpiQuery query); - - /** + void registerSecondaryQueries(List queryJoins, List lazyJoins); + + /** * Return the node for a given path which is used by AutoTune profiling. */ ObjectGraphNode getObjectGraphNode(String path); diff --git a/src/main/java/com/avaje/ebeaninternal/api/SpiQuery.java b/src/main/java/com/avaje/ebeaninternal/api/SpiQuery.java index 5b137ae40..8a472a7d0 100644 --- a/src/main/java/com/avaje/ebeaninternal/api/SpiQuery.java +++ b/src/main/java/com/avaje/ebeaninternal/api/SpiQuery.java @@ -289,16 +289,6 @@ public interface SpiQuery extends Query { */ 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 extends Query { 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. diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/DefaultServer.java b/src/main/java/com/avaje/ebeaninternal/server/core/DefaultServer.java index 7119dc9be..65b6382f6 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/core/DefaultServer.java +++ b/src/main/java/com/avaje/ebeaninternal/server/core/DefaultServer.java @@ -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 request = new OrmQueryRequest(this, queryEngine, query, desc, (SpiTransaction) t); - request.prepareQuery(); + request.prepareQuery(queryBatchSize); return request; } diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/OrmQueryRequest.java b/src/main/java/com/avaje/ebeaninternal/server/core/OrmQueryRequest.java index f67908495..69288b7be 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/core/OrmQueryRequest.java +++ b/src/main/java/com/avaje/ebeaninternal/server/core/OrmQueryRequest.java @@ -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 extends BeanRequest implements BeanQueryRe private CQueryPlanKey queryPlanKey; + private List queryJoins; + + private List lazyJoins; + /** * Create the InternalQueryRequest. */ @@ -143,8 +148,14 @@ public final class OrmQueryRequest 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 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 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 extends BeanRequest implements BeanQueryRe */ @SuppressWarnings("unchecked") public Set findSet() { - return (Set)queryEngine.findMany(this); + return (Set) queryEngine.findMany(this); } /** diff --git a/src/main/java/com/avaje/ebeaninternal/server/loadcontext/DLoadContext.java b/src/main/java/com/avaje/ebeaninternal/server/loadcontext/DLoadContext.java index db7f1c366..efd6490bd 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/loadcontext/DLoadContext.java +++ b/src/main/java/com/avaje/ebeaninternal/server/loadcontext/DLoadContext.java @@ -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. - *

- * The parts of the secondary queries are removed and used - * by LoadBeanContext/LoadManyContext to build the appropriate - * queries. - *

+ * Register the +query and +lazy secondary queries with their appropriate LoadBeanContext or LoadManyContext. */ - public void registerSecondaryQueries(SpiQuery query) { + public void registerSecondaryQueries(List queryJoins, List 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 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); diff --git a/src/main/java/com/avaje/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/src/main/java/com/avaje/ebeaninternal/server/querydefn/DefaultOrmQuery.java index d6608f104..2fb6afb81 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/querydefn/DefaultOrmQuery.java +++ b/src/main/java/com/avaje/ebeaninternal/server/querydefn/DefaultOrmQuery.java @@ -378,12 +378,14 @@ public class DefaultOrmQuery implements SpiQuery { /** * 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 implements SpiQuery { 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 implements SpiQuery { 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); }