I discovered an issue with the Resolve Sitecore Pipeline step in DEF 1.4.1 on Sitecore 8.2 where my Pipeline Batch process would occasionally return and attempt to update the wrong item. In this post, I will explore how that is possible and provide a simple solution to prevent it from occurring.
The OOTB Resolve Sitecore Item pipeline step asks you for the Identifier Value Accessor field in the Identifier section of the configuration. As mentioned in a previous post this is used to locate the item in the index.
If you crack open your search log after a Batch pipeline has run you will see all queries generated by the Resolve Sitecore Item Processor and they only contain the field specified in the Identifier Value Accessor.
If you are syncing complex data structures with parent-child relationships with the same field name existing on a parent record perhaps as a unique key it might also exist on a child record like a product variant as a foreign key. So you have two different templates in Sitecore that share the same field. Not uncommon as sharing fields is a recommended IA best practice.
So when you run the Resolve Sitecore item processor there is a high probability it will return the wrong document from the index and therefore attempt to update the wrong item in Sitecore. In fact, it will update the fields on the item returned in context if any of the fields exist in the mapping. This could be extremely problematic.
The Solution
You could fix this by ensuring your resolve fields do not exist on another template or have a different name. But that’s more of a workaround. A better way would be to restrict the template returned in the index search to the exact template you want to update. The Create New section has a field for the New Item to be created but this is not currently being used when searching for an existing item.
To fix the issue you’ll need to create a custom Resolve Sitecore Item Pipeline processor and modify the DoSearch method. If we include this TemplateID in the list of SearchFilters that are passed in the ItemSearchSettings to the ItemModelRepository Search Method along with the existing Identifier Value Accessor. So that it not only looks for the field but also the template type.
IEnumerable<ItemModel> enumerable = repository.Search(new ItemSearchSettings | |
{ | |
SearchFilters = | |
{ | |
new SearchFilter | |
{ | |
FieldName = sitecoreItemFieldReader.FieldName, | |
Value = text | |
}, | |
new SearchFilter | |
{ | |
FieldName = "TemplateID", | |
Value = resolveItemSettings.TemplateForNewItem.ToString() | |
} | |
} | |
}); |
Now when your pipeline step runs and you crack open the search log you will see the search query now includes the template. Excellent!!
ManagedPoolThread #2 14:54:13 INFO Solr Query – ?q=(((text:(***) OR _name:(***)) AND _template:(891424909af2e148965e7ea10fa7d579)) AND uniqueproductid_t:(“123_45687A_EFG_90_H”))&rows=10&fl=*,score&fq=_indexname:(sitecore_master_index)
Additional Info
Party On Dudes & Dudettes!!