There's been a bit of discussion (I might even go as far as to say ranting 😉 ) on the subject of not using "fast query" in your website code recently. I'm a supporter of this idea – but I came across an issue recently that points out why it's not always easy to be confident that you're not making use of it indirectly...
So, for the benefit of Google:
After finding this issue in the site's logs, support suggested disabling this operation. Support asked whether the client had any code that made use of fast query, since the descendants table is used by fast queries to find content. But my client was happy that their code didn't include any queries like that.
The change helped with the performance issue, and everything was fine for a while. However a while later the client published a new "store" to their public site, and immediately noticed that it crashed as soon as you tried to add a product to your shopping basket.
After some digging they noticed that Commerce Connect's
EaPlanProvider
class was the source of their problem. On their newly published site, it was failing to resolve the correct engagement plan for basket operations. After some disassembly and digging through the code behind this, we could see that there were two operations in this code that would fail:
EngagementPlanItem engagementPlanItem = Tracker.DefinitionDatabase.Automation().EngagementPlans[engagementPlanName];
where it tries to find the definition item for the engagement plan, and
EngagementPlanStateItem engagementPlanStateItem = engagementPlanItem.States[stateName];
where it tries to find the right state item in that plan.
Under the surface, both of these lines of code call the
Sitecore.Analytics.Data.Items.ItemRecords<TItemType>
object's
GetName()
method. And when you look at the innards of that:
private TItemType FindByName(string name) { Assert.ArgumentNotNull(name, "name"); ItemUtil.AssertItemName(name); if (root != null) { string format = deep ? "fast://*[@@id = {0}]//*[@@name = {1}]" : "fast://*[@@id = {0}]/*[@@name = {1}]"; string query = string.Format(format, EscapeQueryParameter(root.ID.Guid.ToString()), EscapeQueryParameter(name)); Item[] array = root.Database.SelectItems(query); if (array != null && array.Length > 0) { Item[] array2 = array; foreach (Item item in array2) { if (templateFilter(item)) { return Wrap(item); } } } } return default(TItemType); }
It makes a fast query!
So the client's problem was that publishing a brand new store also published brand new Engagement Plan items to go with the store. And since Publishing Service is now configured not to update the descendants table, this fast query is never going to return the correct items, and you get a null reference exception...
So if you're seeing similar issues when making use of Commerce Connect with publishing service, you'll need to consider one of two work-arounds:
I've raise a query with Support about this issue, and they've accepted that it is a bug in the product. Hopefully we'll see a fix for this in the not too distant future. But in the meantime, if you have the same problem and want to hurry the fix along, the bug ticket numbers are 291129 and 291130.
↑ Back to top