cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mike Kienenberger <mkien...@gmail.com>
Subject Re: No willPerform(Generic)Query support for prefetching queries in 3.1?
Date Tue, 24 Sep 2013 17:03:15 GMT
>From what testing I've done so far, the qualifier isn't put on for
prefetch queries, which leaves me at the same situation as when using
my datacontext delegate.

And I also have one case where I need to be able to disable the
qualifier on a specific entity for a specific datacontext.
I don't think this is possible even if the modeler qualifier was
working in all other cases.   I consider doing something else, like an
SQL template, but I'd still have entities being fetched in this
situation where foreign keys from that entity wouldn't find a matching
foreign entity due to qualifier restriction.



On Tue, Sep 24, 2013 at 12:07 PM, Andrus Adamchik
<andrus@objectstyle.org> wrote:
>>> 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 <mkienenb@gmail.com> 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 <mkienenb@gmail.com> 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.
>>
>

Mime
View raw message