[ 
https://issues.apache.org/jira/browse/CAY-1681?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13237821#comment-13237821
 ] 

Andrus Adamchik edited comment on CAY-1681 at 3/25/12 10:24 AM:
----------------------------------------------------------------

Andrei, thanks. Looks great. I am attaching my version of your patch with some 
minor styling changes (explicit imports without *, deprecation comments 
containing "@deprecated since 3.1).. The logic is unchanged. 

A few notes on the patch contents:

1. We need to cover a few more cases via unit tests. Here are a few that come 
to mind:  prefetching on to-one relationships; prefetching on multi-column 
relationships (I don't think this one will work, see below)

2. The existing unit tests should attempt to access prefetched object 
properties inside 'queryInterceptor.runWithQueriesBlocked'. This is the 
ultimate test that the objects are in a fully resolved state and will not 
trigger a query when read by the app code

3. HierarchicalObjectResolver allJoinsQualifier.andExp(joinQualifier) is a 
noop, as 'andExp' returns a new expression instance instead of appending to the 
existing one. I know this is inconsistent with SelectQuery.andExp and is one of 
the Cayenne gotchas. I guess we can start by writing a unit test that shows 
this as a problem.

4. Check this code:
+                    Object targetValue = ((DataRow) 
dataRow).get(join.getTargetName());
+                    Expression joinQualifier = 
ExpressionFactory.matchDbExp(join.getSourceName(), targetValue);

I think this is backwards. The join source and target names are used 
incorrectly. The root of prefetch query is "target", not  "source" of the join. 
This only works with your tests because PK and FK have the same name 
(ARTIST_ID). Yeat another reason to expand the test coverage.
                
      was (Author: andrus):
    Andrei, thanks. Looks great. I am attaching my version of your patch with 
some minor styling changes (explicit imports without *, deprecation comments 
containing "@deprecated since 3.1).. The logic is unchanged. 

A few notes on the patch contents:

1. We need to cover a few more cases via unit tests. Here are a few that come 
to mind:  prefetching on to-one relationships; prefetching on multi-column 
relationships (I don't think this one will work, see below)

2. The existing unit tests should attempt to access prefetched object 
properties inside 'queryInterceptor.runWithQueriesBlocked'. This is the 
ultimate test that the objects are in a fully resolved state and will not 
trigger a query when read by the app code

3. HierarchicalObjectResolver allJoinsQualifier.andExp(joinQualifier) is a 
noop, as 'andExp' returns a new expression index instead of appending to the 
existing one. I know this is inconsistent with SelectQuery.andExp and is one of 
the Cayenne gotchas. I guess we can start by writing a unit test that shows 
this as a problem.

4. Check this code:
+                    Object targetValue = ((DataRow) 
dataRow).get(join.getTargetName());
+                    Expression joinQualifier = 
ExpressionFactory.matchDbExp(join.getSourceName(), targetValue);

I think this is backwards. The join source and target names are used 
incorrectly. Rhe root of prefetch query is "target", not  "source" of the join. 
This only works with your tests because PK and FK have the same name 
(ARTIST_ID). Yeat another reason to expand the test coverage.
                  
> Third prefetch kind - DISJOINT_BY_ID
> ------------------------------------
>
>                 Key: CAY-1681
>                 URL: https://issues.apache.org/jira/browse/CAY-1681
>             Project: Cayenne
>          Issue Type: Task
>          Components: Core Library
>            Reporter: Andrus Adamchik
>            Assignee: Andrus Adamchik
>         Attachments: 0001-CAY-1681-Third-prefetch-kind-DISJOINT_BY_ID.patch, 
> CAY-1681.patch
>
>
> (here is a mailing list thread discussing the issue: 
> http://markmail.org/message/zzyd26ucfwhnacfe )
> I keep encountering a common scenario where neither JOINT or DISJOINT 
> prefetch strategies are adequate - queries with fetch limit. It is very 
> common in the application to display X most recent entries from a table with 
> millions of rows, and then drill down to the object details. E.g. assume 2 
> entities - "Order" and "LineItem", with orders having multiple line items. We 
> want 10 most recent orders, with line items prefetched, so you'd so something 
> like this:
>  SelectQuery q = new SelectQuery(Order.class);
>  q.addPrefetch("lineItems");
>  q.setFetchLimit(10);
> "Disjoint" prefetch in this situation would fetch 10 orders and ALL LineItems 
> in DB. 
> "Joint" prefetch will fetch anywhere between 1 and 10 orders, depending on 
> how many line items the first 10 orders have, i.e. fetch limit is applied to 
> to-many join, not to the query root. And this is certainly not what we want. 
> Now Cayenne already has something that can solve the problem:
> q.setPageSize(10); // same as fetch limit
> Paginated query is the most optimal way to prefetch here. Whenever a result 
> list is accessed, Cayenne would execute 2 IN () queries - one for the Orders, 
> another one - for the LineItems. Both queries are matching on a set of Order 
> PKs and are pretty efficient, and only return the objects that we care about.
> The problem with this solution is that it is counterintuitive to the user 
> (why should I set "pageSize" to make my prefetches work) and adds one extra 
> query (the IN query resolving the root object list). Would be cool to turn it 
> into a separate type of prefetch.  Something like "disjoint by id"?

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to