Skip to Content
0
Former Member
Feb 15, 2017 at 09:46 PM

Data Hub - Sort collection attribute

168 Views

We are using the DataHubOutboundService in Hybris 6.1 to send Raw data to Data Hub. We currently have it working to represent the Ids in a parent to children relationship using a collection attribute in our Canonical and Target models like so:

From Raw Item:

 ...
 <attribute>
     <name>r_pk</name>
 </attribute>
 <attribute>
     <name>r_childPk</name>
 </attribute>
 ...

From Canonical Item:

 ...
 <attribute>
     <name>c_id</name>
     <model>
         <localizable>false</localizable>
         <collection>false</collection>
         <type>String</type>
         <primaryKey>true</primaryKey>
     </model>
     <transformations>
         <transformation>
             <rawSource>MyRawItem</rawSource>
             <expression>r_pk</expression>
         </transformation>
     </transformations>
 </attribute>
 <attribute>
     <name>c_children</name>
     <model>
         <localizable>false</localizable>
         <collection>true</collection>
         <type>String</type>
         <primaryKey>false</primaryKey>
     </model>
     <transformations>
         <transformation>
             <rawSource>MyRawItem</rawSource>
             <expression>r_childPk</expression>
         </transformation>
     </transformations>
 </attribute>
 ...

From Target Item:

 ...
 <attribute>
     <name>id</name>
     <localizable>false</localizable>
     <collection>false</collection>
     <transformationExpression>c_id</transformationExpression>
     <exportCode>id</exportCode>
 </attribute>
 <attribute>
     <name>children</name>
     <localizable>false</localizable>
     <collection>true</collection>
     <transformationExpression>c_children</transformationExpression>
     <exportCode>children</exportCode>
 </attribute>
 ...

Right now, after composition, the sequence of the values in the children collection often differs from how the sorted Raw data was originally sent in. We are trying to figure out how to maintain the sequence of the values so that the sort order can be correctly sent to our Target system.

We read that all RawItems are given a unique, sequential Id as they are created. We have verified that when we use the DataHubOutboundService like we are using it, these Raw Ids do correctly indicate the order that we want our values to be in. So, we tried adding a CompositionRuleHandler to sort the collection values using the Raw Ids to restore the order we want the collection values to be in.

From CompositionRuleHandler compose method:

 ...
 // sort original RawItems by their generated id which maintains the order they were added
 final List<? extends RawItem> rawItems = compositionGroup.getItems();
 final List<RawItem> sortedItems = new ArrayList<>(rawItems);
 sortedItems.sort((i1, i2) -> i1.getId().compareTo(i2.getId()));

 // refetch collection values in sorted order
 final List<Object> sortedValues = new ArrayList<>();
 for (final RawItem rawItem : sortedItems)
 {
     final Object value = this.transformExpression(attributeDefinition, canonicalItem, rawItem);
     if (value != null)
     {
         sortedValues.add(value);
     }
 }

 // replace unsorted collection with new sorted values
 final String attributeName = attributeDefinition.getCanonicalAttributeModelDefinition()
                                 .getAttributeName();
 LOG.debug(attributeName + " Before sort: " + canonicalItem.getField(attributeName));
 canonicalItem.setField(attributeName, sortedValues);
 LOG.debug(attributeName + " After sort: " + canonicalItem.getField(attributeName));
 ...

With our debugging, we can see that our sorting logic does rearrange the values back into the desired order during composition. However, when we look at the resulting CanonicalItems and TargetItems, the order is incorrect again.

So our question is:
How do we maintain the original order that our raw values are in when they are composed into a Canonical collection attribute? (And also keep the same order as they are published to TargetItems too.)

Any help would be appreciated.