>> I still need a way to filter all query >> types for specific entities to filter out certain entities (appending >> "where INVALIDATED = 'N'").
Is this a global rule, or does it depend on some context (like user role)? If it's the former, you can add a qualifier to affected entities in the Modeler. Andrus On Sep 24, 2013, at 7:00 PM, Mike Kienenberger <[email protected]> wrote: > Here's one possible way to add support for intercepting prefetch > queries. I'm not entirely certain it's the best way, but I didn't > see another obvious point. > > What I did was to call > QueryRouter.willPerformQuery(PrefetchSelectQuery query) before routing > the newly-created prefetch select query. > > For DataDomainQueryAction, this will call context.willPerformQuery() > if there's a non-null context. > For anything else (DataDomainLegacyQueryAction, MockQueryRouter), it's a noop. > > If the returned query is null, then we skip routing the query and > return either true or false. I picked true since it might be useful > to process children of the prefetch even if the prefetch is not > skipped. My own use case is never going to return null, so I'm fine > with false. > > There's also no reason why I picked > QueryRouter.willPerformQuery(PrefetchSelectQuery query) instead of > QueryRouter.willPerformQuery(Query query) other than it made it more > obvious that this method was only being used for > PrefetchSelectQueries. But there may be other kinds of queries which > should also be going through this method. The more I think about > this, the more reasonable it seems have it be Query since developers > might be writing their own Query types, and any Queries being created > internally should be exposed through > DataContextDelegate.willPerformQuery, and the QueryRouter is the most > likely place to be able to forward such new queries. > > This has solved my issues with prefetching under 3.1. I'm still open > to suggestions for solving my specific problem another way in the > application code (adding database table views isn't an option), but I > think exposing prefetch queries (as well as others) is something we > should be supporting in Cayenne. > > > Index: > framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainLegacyQueryAction.java > =================================================================== > --- > framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainLegacyQueryAction.java > (revision 1524993) > +++ > framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainLegacyQueryAction.java > (working copy) > @@ -27,6 +27,7 @@ > > import org.apache.cayenne.CayenneRuntimeException; > import org.apache.cayenne.map.DataMap; > +import org.apache.cayenne.query.PrefetchSelectQuery; > import org.apache.cayenne.query.Query; > import org.apache.cayenne.query.QueryMetadata; > import org.apache.cayenne.query.QueryRouter; > @@ -163,4 +164,8 @@ > > return q != null ? q : executedQuery; > } > + > + public Query willPerformQuery(PrefetchSelectQuery prefetchQuery) { > + return prefetchQuery; > + } > } > Index: > framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java > =================================================================== > --- > framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java > (revision 1524993) > +++ > framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java > (working copy) > @@ -772,4 +772,14 @@ > } > } > } > + > + public Query willPerformQuery(PrefetchSelectQuery prefetchQuery) { > + // Notify DataContextDelegate that we have created a new > PrefetchSelectQuery > + if (null != context) { > + Query transformedQuery = > context.nonNullDelegate().willPerformQuery(context, prefetchQuery); > + return transformedQuery; > + } else { > + return prefetchQuery; > + } > + } > } > Index: > framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/QueryRouter.java > =================================================================== > --- > framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/QueryRouter.java > (revision 1524993) > +++ > framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/QueryRouter.java > (working copy) > @@ -49,4 +49,6 @@ > * @throws NullPointerException if a map parameter is null. > */ > QueryEngine engineForDataMap(DataMap map); > + > + Query willPerformQuery(PrefetchSelectQuery prefetchQuery); > } > Index: > framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/SelectQueryPrefetchRouterAction.java > =================================================================== > --- > framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/SelectQueryPrefetchRouterAction.java > (revision 1524993) > +++ > framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/SelectQueryPrefetchRouterAction.java > (working copy) > @@ -114,9 +114,15 @@ > > // pass prefetch subtree to enable joint prefetches... > prefetchQuery.setPrefetchTree(node); > - > + > + Query transformedQuery = router.willPerformQuery(prefetchQuery); > + if (null == transformedQuery) { > + // Not sure if we want to return false instead. > Returning true seems safer. > + return true; > + } > + > // route... > - prefetchQuery.route(router, resolver, null); > + transformedQuery.route(router, resolver, null); > return true; > } > > Index: > framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/query/MockQueryRouter.java > =================================================================== > --- > framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/query/MockQueryRouter.java > (revision 1524993) > +++ > framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/query/MockQueryRouter.java > (working copy) > @@ -50,4 +50,8 @@ > public QueryEngine engineForDataMap(DataMap map) { > return new MockQueryEngine(); > } > + > + public Query willPerformQuery(PrefetchSelectQuery prefetchQuery) { > + return prefetchQuery; > + } > } > > > > On Mon, Sep 23, 2013 at 7:04 PM, Mike Kienenberger <[email protected]> wrote: >> All of my tests pass now, but I'm still hitting a few issues for 3.1 >> that the tests didn't reveal. >> >> In previous versions (not sure when it changed), there existed the >> ability to intercept prefetch queries using >> DataContextDelegate.willPerformQuery() or willPerformGenericQuery(). >> Those queries are no longer available -- only the original query with >> the prefetchTree goes through those methods. >> >> It's the end of the day here, so I haven't traced through the code yet >> to see what's going on, but I still need a way to filter all query >> types for specific entities to filter out certain entities (appending >> "where INVALIDATED = 'N'"). I've got this working for select >> queries, relationship queries, objectIdQueries, but not prefetch >> queries. >> >> And I'm still wondering what the difference between >> willPerformGenericQuery and willPerformQuery might be. So far, I >> just forward willPerformGenericQuery requests through my >> willPerformQuery code. >
