Search This Blog

Monday, June 23, 2014

Inventory Index doesn't return correct value

When you have one fulfilment center configured with NON-ATP inventory system. It works fine when you have multiple fulfilment centers configured. Inventory buildindex process doesn’t index correct data for first two records in inventory table. First record from inventory table get inventory value from second record and second record from inventory doesn’t even indexed. There is coding issue in “com.ibm.commerce.foundation.internal.server.services.search.dataimport.solr.MultiplexSqlEntityProcessor” configured in wc-data-config.xml for inventory index core.

For example : here is result of SQL from database.






After index here is result from index.














As you can see inventory value (1327.0) of first record (catentry_id=79354) is wrong. Inventory value (1327.0) is coming from second  record (catentry_id=87508). Secondly catentry record 87508 is missing from index.

This issue is in IBM code  (com.ibm.commerce.foundation.internal.server.services.search.dataimport.solr.MultiplexSqlEntityProcessor). This class is available as loose class in Solr.war.

Here is snippet of buggy code (Bold Red color). On first iteration. As you can see iLookAheadPrimaryKey is initialized as null. On execution of this method first its calling multiplex from current row (first record). Multiplex method just fills store_id, ffmcenter_id and quantity in solr search pattern for inventory filter for current record (catentry_id). For example: inv_strffmqty_<store_id>_<ffmcenter_id>=<quantity>.

On first iteration of loop iLookAheadPrimaryKey value is null hence it goes in else block and again calls Multiplex method on same record and Multiplex method maps inventory value from next record to same record. Finally wrong data gets indexed. 

  private List<Map<String, String>> iEntityFields = null;
  private Map<String, Object> iLookAheadRow = null;
  private String iLookAheadPrimaryKey = null;
  private String iPrimaryKeyColumn = null;
  private String iPrimaryKeyField = null;





public Map<String, Object> nextRow()
  {
    String METHODNAME = "nextRow()";
   // SearchLogger.entering(SEARCHLOGGER, CLASSNAME, "nextRow()");
    if (!this.iHasNext)
    {
     // SearchLogger.exiting(SEARCHLOGGER, CLASSNAME, "nextRow()",
      //  "null");
      return null;
    }
    Map<String, Object> currentRow = null;
    if (this.iLookAheadRow == null) {
      currentRow = super.nextRow();
    } else {
      currentRow = this.iLookAheadRow;
    }
    currentRow = multiplex(currentRow, currentRow);
    while (currentRow != null)
    {
      this.iLookAheadRow = super.nextRow();
      //this.iLookAheadPrimaryKey = String.valueOf(this.iLookAheadRow.get(this.iPrimaryKeyColumn));
      if (this.iLookAheadRow != null)
      {
        Object primaryKeyFieldObject = this.iLookAheadRow.get(this.iPrimaryKeyColumn);
        String primaryKeyValue = null;
        if (primaryKeyFieldObject != null) {
          primaryKeyValue = String.valueOf(primaryKeyFieldObject);
        }
        if ((this.iLookAheadPrimaryKey != null) &&
          (this.iLookAheadPrimaryKey.length() > 0))
        {
          if (this.iLookAheadPrimaryKey.equals(primaryKeyValue))
          {
            currentRow = multiplex(currentRow, this.iLookAheadRow);
          }
          else
          {
            this.iLookAheadPrimaryKey = primaryKeyValue;
            break;
          }
        }
        else
        {
          currentRow = multiplex(currentRow, this.iLookAheadRow);
          this.iLookAheadPrimaryKey = primaryKeyValue;

        }
      }
      else
      {
        this.iLookAheadPrimaryKey = null;
        this.iHasNext = false;
        break;
      }
    }
   // SearchLogger.exiting(SEARCHLOGGER, CLASSNAME, "nextRow()", currentRow);
    return currentRow;
  }

Quick solution of this problem is to customize “com.ibm.commerce.foundation.internal.server.services.search.dataimport.solr.MultiplexSqlEntityProcessor” and initialize iLookAheadPrimaryKey with some string. For example private String iLookAheadPrimaryKey = “00”;



1 comment:

  1. Hi Neeraj,
    We are also facing similar issue and raised a PMR also.
    But its clear from your blog as why the problem is there in first place.Thanks for putting this issue here in great details.

    ReplyDelete