cayenne-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Andrus Adamchik <and...@objectstyle.org>
Subject Re: Problem with joint prefetch and flattened attributes
Date Wed, 06 Aug 2014 09:55:16 GMT
> But it would really help us a lot if we could get this to
> work, so maybe I can find the time later.


Yeah, would be cool if you get a chance to try it out with a HEAD build of either master or
3.1, and see which problems still remain.

Thanks for the information you shared so far.

Andrus

On Aug 6, 2014, at 12:35 PM, Erlend Birkenes <eb@dataloy.com> wrote:

> Ok, I'll Jira it when I have a moment.
> 
> But I also just discovered that all the flattened attributes are null in
> the resolved objects (and in the DataRow), even though the data is present
> in the query result.
> 
> I was hoping there would be a quick fix to let me use joint prefetch, but
> this, together with the problem with combining joint and disjoint_by_id,
> makes me think that joint prefetch has more problems than I thought. I'll
> go back to using only disjoint_by_id and not dig any deeper into this, at
> least for now. But it would really help us a lot if we could get this to
> work, so maybe I can find the time later.
> 
> –
> Erlend <http://www.dataloy-systems.com>
> 
> 
> 2014-08-06 8:40 GMT+02:00 Andrus Adamchik <andrus@objectstyle.org>:
> 
>> Actually, checking the release notes [1], we have a bunch of
>> prefetch-related fixes in (yet unreleased) 3.2M2 - CAY-1928, CAY-1695,
>> CAY-1905. 1905 and 1928 are also fixed on 3.1 branch
>> 
>> Could you maybe try your case with a source code build of Cayenne (either
>> 3.1 or master) ?
>> 
>> Thanks,
>> Andrus
>> 
>> [1]
>> https://github.com/apache/cayenne/blob/master/docs/doc/src/main/resources/RELEASE-NOTES.txt
>> [2]
>> https://github.com/apache/cayenne/blob/STABLE-3.1/docs/doc/src/main/resources/RELEASE-NOTES.txt
>> 
>> On Aug 6, 2014, at 9:34 AM, Andrus Adamchik <andrus@objectstyle.org>
>> wrote:
>> 
>>>> This is clearly a bug. Should I create a JIRA issue?
>>> 
>>> Hi Erlend,
>>> 
>>> Yes, please Jira it. Sounds like a bug.
>>> 
>>> Thanks,
>>> Andrus
>>> 
>>> 
>>> On Aug 5, 2014, at 2:07 PM, Erlend Birkenes <eb@dataloy.com> wrote:
>>> 
>>>> Hi
>>>> 
>>>> I discovered a problem with joint prefetch and flattened attributes.
>> This
>>>> is in 3.1B2 which is the version we use at the moment. Not sure if this
>> is
>>>> the lates or not..
>>>> 
>>>> If I have a entity A with a normal relationship to an entity B, and B
>> has
>>>> flattened attributes from C via toCdbrel.SOME_PROPERTY.
>>>> This works fine normally. But when using joint prefetch the table
>> aliases
>>>> in the query will be wrong. (Querying A and prefetching B).
>>>> If there are multiple flattened attributes, C will also be joined in
>>>> multiple times.
>>>> 
>>>> The problem is in SelectTranslator#appendQueryColumns.
>>>> This section adds columns from the target entity of a joint prefetch,
>>>> including relationships for flattened attributes:
>>>> 
>>>> while (targetObjAttrs.hasNext()) {
>>>>      ObjAttribute oa = targetObjAttrs.next();
>>>>      Iterator<CayenneMapEntry> dbPathIterator = oa.getDbPathIterator();
>>>>      while (dbPathIterator.hasNext()) {
>>>>              Object pathPart = dbPathIterator.next();
>>>> 
>>>>              if (pathPart == null) {
>>>>                      throw new CayenneRuntimeException(
>>>>                                      "ObjAttribute has no component: "
>> +
>>>> oa.getName());
>>>>              }
>>>>              else if (pathPart instanceof DbRelationship) {
>>>>                      DbRelationship rel = (DbRelationship) pathPart;
>>>>                      dbRelationshipAdded(rel, JoinType.INNER, null);
>>>> //PROBLEM
>>>>              }
>>>>              else if (pathPart instanceof DbAttribute) {
>>>>                      DbAttribute attribute = (DbAttribute) pathPart;
>>>> 
>>>>                      appendColumn(columns, oa, attribute, attributes,
>>>> labelPrefix
>>>>                                      + '.'
>>>>                                      + attribute.getName());
>>>>              }
>>>>      }
>>>> }
>>>> 
>>>> The problem is that dbRelationshipAdded sets the topNode of the
>> JoinStack
>>>> to the new node when a relationship is added and this is never reset in
>>>> this case. So every time a relationship is added in this loop it will
>> add a
>>>> node to the previously added node. This will increase the tableAlias by
>> 1
>>>> for every relationship, and also cause any attributes directly on B to
>>>> belong to the wrong node and therefore get the wrong tableAlias. It will
>>>> also cause an additional join, but joined to the wrong table.
>>>> 
>>>> The topNode of the JoinStack needs to be reset to the correct value
>> after
>>>> handing each attribute, or more presisely: after the "while
>>>> (dbPathIterator.hasNext())" loop the topNode needs to be the same as it
>> was
>>>> before the loop, because we are still processing attributes on the same
>>>> entity (B in this case).
>>>> 
>>>> Storing the current topNode, and resetting it after processing each
>>>> attribute fixed the problem for me. Like this:
>>>> 
>>>> while (targetObjAttrs.hasNext()) {
>>>>                  JoinTreeNode topNode = getJoinStack().topNode;  // FIX
>>>>                  ObjAttribute oa = targetObjAttrs.next();
>>>>                  Iterator<CayenneMapEntry> dbPathIterator =
>>>> oa.getDbPathIterator();
>>>>                  while (dbPathIterator.hasNext()) {
>>>>                      Object pathPart = dbPathIterator.next();
>>>> 
>>>>                      if (pathPart == null) {
>>>>                          throw new CayenneRuntimeException(
>>>>                                  "ObjAttribute has no component: " +
>>>> oa.getName());
>>>>                      }
>>>>                      else if (pathPart instanceof DbRelationship) {
>>>>                          DbRelationship rel = (DbRelationship)
>> pathPart;
>>>>                          dbRelationshipAdded(rel, JoinType.INNER,
>> null);
>>>>                      }
>>>>                      else if (pathPart instanceof DbAttribute) {
>>>>                          DbAttribute attribute = (DbAttribute)
>> pathPart;
>>>> 
>>>>                          appendColumn(columns, oa, attribute,
>>>> attributes, labelPrefix
>>>>                                  + '.'
>>>>                                  + attribute.getName());
>>>>                      }
>>>>                  }
>>>>                  getJoinStack().topNode = topNode; // FIX
>>>>              }
>>>> 
>>>> resetJoinStack() can't be used in this case, since we don't want the
>>>> rootNode.
>>>> 
>>>> I've run the Cayenne tests after this change with no errors, but I've
>> only
>>>> done limited testing in our own app so far.
>>>> 
>>>> This is clearly a bug. Should I create a JIRA issue?
>>>> 
>>>> 
>>>> –
>>>> Erlend <http://www.dataloy-systems.com>
>>> 
>>> 
>> 
>> 


Mime
View raw message