@VisibleForTesting void writeToSalesForce(Object[] rowData) throws KettleException { try { if (log.isDetailed()) { logDetailed( "Called writeToSalesForce with " + data.iBufferPos + " out of " + meta.getBatchSizeInt()); } // if there is room in the buffer if (data.iBufferPos < meta.getBatchSizeInt()) { // Reserve for empty fields ArrayList<String> fieldsToNull = new ArrayList<String>(); ArrayList<MessageElement> updatefields = new ArrayList<MessageElement>(); // Add fields to update for (int i = 0; i < data.nrfields; i++) { boolean valueIsNull = data.inputRowMeta.isNull(rowData, data.fieldnrs[i]); if (valueIsNull) { // The value is null // We need to keep track of this field fieldsToNull.add( SalesforceUtils.getFieldToNullName( log, meta.getUpdateLookup()[i], meta.getUseExternalId()[i])); } else { updatefields.add( SalesforceConnection.createMessageElement( meta.getUpdateLookup()[i], rowData[data.fieldnrs[i]], meta.getUseExternalId()[i])); } } // build the SObject SObject sobjPass = new SObject(); sobjPass.setType(data.connection.getModule()); if (updatefields.size() > 0) { sobjPass.set_any(updatefields.toArray(new MessageElement[updatefields.size()])); } if (fieldsToNull.size() > 0) { // Set Null to fields sobjPass.setFieldsToNull(fieldsToNull.toArray(new String[fieldsToNull.size()])); } // Load the buffer array data.sfBuffer[data.iBufferPos] = sobjPass; data.outputBuffer[data.iBufferPos] = rowData; data.iBufferPos++; } if (data.iBufferPos >= meta.getBatchSizeInt()) { if (log.isDetailed()) { logDetailed("Calling flush buffer from writeToSalesForce"); } flushBuffers(); } } catch (Exception e) { throw new KettleException("\nFailed in writeToSalesForce: " + e.getMessage()); } }