Jadon Hansell created CAY-2909:
----------------------------------

             Summary: Vertical Inheritence: Unnecessary Disjoint-By-Id Prefetch 
Query
                 Key: CAY-2909
                 URL: https://issues.apache.org/jira/browse/CAY-2909
             Project: Cayenne
          Issue Type: Bug
    Affects Versions: 5.0-M1
            Reporter: Jadon Hansell
         Attachments: unnecessary-prefetch-fix.patch

Using the entities from the {{inheritance-vertical}} test map:

{{IvBase}} has a child entity {{IvImpl}}. Say we have a one-to-many 
relationship from {{IvImpl}} to {{IvOther}} called {{other}}. The important 
part is that the foreign key is on the child entity's table: 
{{IV_IMPL.OTHER_ID}}. The db relationship path would start from {{IV_BASE}} and 
be {{impl.other}}.

The reverse relationship would be many-to-one from {{IvOther}} to {{IvImpl}} 
called {{relatedImpls}} (or similar). The db relationship path would start from 
{{IV_OTHER}} and be {{relatedImpls.base}}.

Because it is a flattened relationship, 
{{ObjRelationship.isSourceIndependentFromTargetChange()}} returns {{true}} for 
the {{IvImpl.other}} relationship. This causes 
{{HierarchicalObjectResolver.processDisjointByIdNode}} to add the reverse 
relationship to the query, and for the {{PrefetchPrcessorTreeBuilder}} to 
choose the {{JoinedIdParentAttachmentStrategy}}. On most flattened paths this 
works well.

In this case, since {{IvImpl}} is a child entity, the data row for the root 
entity of the query already contains the path {{impl.OTHER_ID}}, so we already 
have the id and this extra query for the reverse relationship is unnecessary.

I've attached a (very) experimental patch that fixes this issue on master. I'm 
not super familiar with this part of the codebase, so I've probably overlooked 
some edge cases. It introduces an {{isFkOnChildEntity}} method on 
{{ObjRelationship}} that allows me to check for this edge case and avoid 
querying the reverse relationship. I then updated 
{{ResultScanParentAttachmentStrategy}} to handle this case by adding the 
appropriate prefix ({{"impl."}}) to get the id off of the {{DataRow}}.

I'm not sure how to write a breaking test for an unnecessary extra query, but 
when I manually tested it in my own environment it reduced the execution time 
of some queries from ~10s to ~100ms.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to