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)