Version: AX 2012 FPK

Problem description:

When running a P job to pull the data from the POS, the store connect fails while inserting the data back to AX.

The error message is logged in the Event Viewer or Outgoingmessages table is this, depending on the

 tracing options set in the store connect settings.

ORIGINAL MESSAGE

2012.5.30
  16:5:57:989              (8396)      [1]            CCommMgr::HandleException:
  Target request handler failed to process target request header:
  Microsoft.Dynamics.Retail.StoreConnect.Request.AXHandler.SCAXRequestHandlerException:
  AX target request handler failed to process request: AX Managed Interop
  failure. ---> Microsoft.Dynamics.AX.ManagedInterop.ErrorException:           Error
  when bulk inserting data. Target table: RetailTransactionSalesTrans

System.Reflection.TargetInvocationException:
  Exception has been thrown by the target of an invocation. --->
  System.InvalidOperationException: The
  given ColumnMapping does not match up with any column in the source or
  destination.

   at
  System.Data.SqlClient.SqlBulkCopyColumnMappingCollection.Add(SqlBulkCopyColumnMapping
  bulkCopyColumnMapping)

   --- End of inner exception stack trace ---

   at
  System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method,
  Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes
  methodAttributes, RuntimeType typeOwner)

   at System.Reflection.RuntimeMethodInfo.Invoke(Object
  obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo
  culture, Boolean skipVisibilityChecks)

   at
  System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags
  invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)

   at
  Microsoft.Dynamics.AX.ManagedInterop.ClrBridgeImpl.InvokeClrInstanceMethod(ClrBridgeImpl*
  , ObjectWrapper* objectWrapper, Char* pszMethodName, Int32 argsLength,
  ObjectWrapper** arguments, Boolean* argsAreByRef, Boolean* isException)

   at
  Microsoft.Dynamics.AX.ManagedInterop.Object.CallWithReturnType(String
  methodName, Type returnType, Object[] paramList)

   at
  Microsoft.Dynamics.AX.ManagedInterop.Object.Call(String methodName)

   at
  Microsoft.Dynamics.Retail.StoreConnect.Request.AXHandler.SCAXTargetRequestHandler.

ProcessTargetRequestHeader(ISCTargetRequestHeader
  targetRequestHeader)

   --- End of inner exception stack trace ---

   at
  Microsoft.Dynamics.Retail.StoreConnect.Request.AXHandler.SCAXTargetRequestHandler.

ProcessTargetRequestHeader(ISCTargetRequestHeader
  targetRequestHeader)

   at CCommMgr.ProcessTargetRequest(CCommMgr*
  ,
  basic_string<wchar_t\,std::char_traits<wchar_t>\,std::allocator<wchar_t>
  >* r_file_path, SCRequestHandlerManager scRequestHandlerManager)

 

Since this error message only indicates a column mapping issue, it is not very informative.

Reason:

In the following example, we explain why and how we came to the solution.

When we generate Retail seed data in the Retail parameters/initialize,
we are inserting the data from a resource file (AOT). In that process Dynamics
AX is not validating the columns if configuration keys are enabled.

In the example we found out that the customer had disabled the SALES TAX configuration key.

In the table RetailTransactionSalesTrans there are 5 fields
that all are bound to the LedgerBasicSalesTax configuration key (sales tax) which as shown in the picture is
disabled in the configuration keys.


  • TaxAmount

  • TaxGroup

  • TaxItemGroup

  • OriginalTaxGroup

  • OriginalTaxItemGroup

 

 

  

Debugging the issue:

To debug the issue we first had to find were the error message originates from. By looking at the

String “Error when bulk inserting data. Target table: RetailTransactionSalesTrans” we could guess that
we had to look for Error when bulk inserting data. Target table:, which we also found in the class.

\Classes\RetailConnSCDataBulkCopy\bulkCopyToTemp

Enabling a breakpoint in that class and enabling debugging through the business connector, we could step through the code.

 


Through the debugger we saw that we had two containers keeping the source columns and target columns

The two containers are ColumnNames(Source), PhysicalColumnNames (target)


These two containers or list of columns must match; else we have a mapping issue.

 


As shown in the PhysicalColumnNames

The columns 31,32,58,59,60 are missing

As mentioned earlier, these columns were not activated by the configuration keys.

 The call stack of the call


 

 

Solution and modification:

The solution is to either enable the License configuration keys affecting the Retail transaction tables or adjust the subjob transfer
field list.

 

The code change that introduces a better error handling

 

\Classes\RetailConnSCDataBulkCopy\bulkCopyToTemp

public void
  bulkCopyToTemp(str
  physicalTempDBTableName)

{

    System.Data.SqlClient.SqlBulkCopy
  sqlBulkCopy;

    str
  connStr;

   
  System.Data.SqlClient.SqlBulkCopyColumnMappingCollection colMapping;

    str
  columnName;

    str
  dstTableName;

    int
  i;

    System.Xml.XmlReader xmlReader;

   
  Microsoft.Dynamics.Retail.StoreConnect.Request.Base.SCSimpleXmlDataReader
  xmlDataReader;

 

 

   
  System.Collections.Specialized.StringCollection columnNameCollection;

   
  System.Collections.Specialized.StringCollection
  guidColumnNameCollection;

 

    System.Exception clrException;

    str
  exceptionMessage;

 

 //MS CHANGE

    str
  columnName2;

    str
  missingColumns;

 //MS CHANGE

    ;

 

    columnNameCollection = new
  System.Collections.Specialized.StringCollection();

    guidColumnNameCollection = new
  System.Collections.Specialized.StringCollection();

 

 

    for
  (i = 1; i <= conLen(columnNames); i++)

    {

        columnName = conPeek(columnNames, i);

        columnNameCollection.Add(columnName);

    }

 

    for
  (i = 1; i <= conLen(guidColumnNames); i++)

    {

        columnName = conPeek(guidColumnNames, i);

        guidColumnNameCollection.Add(columnName);

    }

 

    try

    {

        xmlReader = new
  System.Xml.XmlTextReader(tmpDataFilePath);

        xmlDataReader = new
  Microsoft.Dynamics.Retail.StoreConnect.Request.Base.SCSimpleXmlDataReader(

            xmlReader,

            columnNameCollection,

            guidColumnNameCollection,

            targetTableName,

            false);

 

        connStr = this.getConnectionString();

        sqlBulkCopy = new
  System.Data.SqlClient.SqlBulkCopy(connStr);

        dstTableName = #TempDBPrefix +
  physicalTempDBTableName;

 

        colMapping =
  sqlBulkCopy.get_ColumnMappings();

 

        for
  (i = 1; i <= conLen(physicalColumnNames); ++i)

        {

            colMapping.Add(i-1, conPeek(physicalColumnNames,
  i));

        }

 

 

 

       
  sqlBulkCopy.set_DestinationTableName(dstTableName);

       
  sqlBulkCopy.set_BulkCopyTimeout(#BulkCopyTimeOut);

 

       
  sqlBulkCopy.WriteToServer(xmlDataReader);

 

        rowsAffected =
  xmlDataReader.get_NumberOfRecordsRead();

 

        sqlBulkCopy.Dispose();

        xmlDataReader.Dispose();

        xmlReader.Dispose();

        this.CleanTempDataFile();

    }

    catch(Exception::CLRError)

    {

        //MS
  CHANGE

        for
  (i = 1; i <= conLen(physicalColumnNames); ++i)

        {

            if(conPeek(physicalColumnNames,i) =="")

                missingColumns += conPeek(columnNames,i) + ",";

        }

 

        clrException =
  CLRInterop::getLastException();

        exceptionMessage =
  clrException.ToString();

        exceptionMessage = strFmt("Error
  when bulk inserting data. \r\nTarget table: %1\r\n Target columns:
  %2\r\n\r\nCheck if these fields are disabled by the license configuration
  keys.\r\nIf the configuration keys are correct, change the transfer field
  list on the scheduler subjob\r\n\r\n%3",

            targetTableName,missingColumns,
  exceptionMessage);

        //MS
  CHANGE

 

        if
  (sqlBulkCopy)

        {

            sqlBulkCopy.Dispose();

        }

 

        if
  (xmlDataReader)

        {

            xmlDataReader.Dispose();

        }

 

 
        if (xmlReader)

        {

            xmlReader.Dispose();

        }

 

        this.CleanTempDataFile();

 

        throw
  error(exceptionMessage);

    }

}

 

 

NEW ERROR MESSAGE

2012.6.1 9:13:45:821                (14376)    [1]            CCommMgr::HandleException:
  Target request handler failed to process target request header:
  Microsoft.Dynamics.Retail.StoreConnect.Request.AXHandler.SCAXRequestHandlerException:
  AX target request handler failed to process request: AX Managed Interop
  failure. ---> Microsoft.Dynamics.AX.ManagedInterop.ErrorException:           Error
  when bulk inserting data.

Target table: RetailTransactionSalesTrans

 Target
  columns:
  OriginalTaxGroup,OriginalTaxItemGroup,TaxAmount,TaxGroup,TaxItemGroup,

 

Check if these fields are disabled by the license configuration keys.

If the configuration keys are correct, change the transfer field list on the scheduler subjob

 

System.Reflection.TargetInvocationException:
  Exception has been thrown by the target of an invocation. --->
  System.InvalidOperationException: The
  given ColumnMapping does not match up with any column in the source or
  destination.

   at System.Data.SqlClient.SqlBulkCopyColumnMappingCollection.Add(SqlBulkCopyColumnMapping
  bulkCopyColumnMapping)

   --- End of inner exception stack trace ---

   at
  System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method,
  Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes
  methodAttributes, RuntimeType typeOwner)

   at
  System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags
  invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean
  skipVisibilityChecks)

   at System.Reflection.RuntimeMethodInfo.Invoke(Object
  obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo
  culture)

   at
  Microsoft.Dynamics.AX.ManagedInterop.ClrBridgeImpl.InvokeClrInstanceMethod(ClrBridgeImpl*
  , ObjectWrapper* objectWrapper, Char* pszMethodName, Int32 argsLength,
  ObjectWrapper** arguments, Boolean* argsAreByRef, Boolean* isException)

   at
  Microsoft.Dynamics.AX.ManagedInterop.Object.CallWithReturnType(String
  methodName, Type returnType, Object[] paramList)

   at Microsoft.Dynamics.AX.ManagedInterop.Object.Call(String
  methodName)

   at
  Microsoft.Dynamics.Retail.StoreConnect.Request.AXHandler.SCAXTargetRequestHandler.

ProcessTargetRequestHeader(ISCTargetRequestHeader
  targetRequestHeader)

   --- End of inner exception stack trace ---

   at
  Microsoft.Dynamics.Retail.StoreConnect.Request.AXHandler.SCAXTargetRequestHandler.

ProcessTargetRequestHeader(ISCTargetRequestHeader
  targetRequestHeader)

   at CCommMgr.ProcessTargetRequest(CCommMgr*
  , basic_string<wchar_t\,std::char_traits<wchar_t>\,std::allocator<wchar_t>
  >* r_file_path, SCRequestHandlerManager scRequestHandlerManager)

 

 

 

Author: Kim Truelsen

Date: 1/6-2012