Montag, 4. April 2016

Problem with XML Input for Bulk API when Using Relationship Fields (INVALID_FIELD_FOR_INSERT_UPDATE)

Few days ago I discovered a strange bug in Salesforce, which costed at least half a day to resolve. The bug concerns the Bulk API and XML input. Suppose you have an input with references like this:

        <sObject>
            <LastName>a1-ContactWithRelationship</LastName>
            <Account>
                <sObject>
                    <account_external_id__c>ab123</account_external_id__c>
                </sObject>
            </Account>
        </sObject>


Here I was trying to update a Contact and set the account reference to a new value.
As a response I got the following error message from Salesforce:

<errors><fields>Account</fields><message>Contact: bad field names on insert/update call: Account</message><statusCode>INVALID_FIELD_FOR_INSERT_UPDATE</statusCode></errors>

The same request sent using REST API succeeded, so I had no evidence what I am doing wrong until I found this thread:

https://developer.salesforce.com/forums/?id=906F00000008kOpIAI

It turned out that this is a bug in SF Bulk API (known for at least 5 years!). To resolve this you have to remove all whitespaces and line breaks in your XML or at least in the sObjects section. So the problem was the pretty-print and that is kind of ridiculous nowadays!

Hope, this would be helpful.

Dienstag, 23. Februar 2016

How to configure sap.application.global.properties

The most SAP PI/PO adapters have some settings which you cannot configure in the PI GUI, for example timeout values, number of connections etc. These settings are normally defined in sap.application.global.properties file. To configure these values go to NetWeaver Administrator (you can use the shortcut nwa) and then Configuration Management -> Infrastructure -> Java System Properties -> Applications and select your application. In Extended Details you can edit the settings under Custom Calculated Value.

Donnerstag, 14. Januar 2016

Limitations of the Bulk and REST Query operations in Salesforce (and possible workarounds)

A few days ago I received a support request from a customer of our SFDC-PI-Adapter. The customer is a big company having hundreds of thousands of records on Salesforce. They implemented a query which would return a big number of records. At first they tried the Bulk API for the query. The problem was that Salesforce does not support foreign keys in Bulk queries, so you can use only one database table, which is not appropriate in the most cases. Despite an urgent need from developers, the support for foreign keys was not implemented by Salesforce yet.

The current solution is to use the REST API for queries. Salesforce allows use of foreign keys in REST API queries. The problem is however that it returns only 2000 records as response to the GET request. The next 2000 records are linked in the so-called nextRecordsUrl which is a part of the response. You can use it for the next request, which also contains a nextRecordsUrl and so on. The adapter uses the nextRecordsUrl to get all the data of the query result. The problem is that if you have a real big amount of data, the adapter have to make a big number of GET requests (one for each 2000 records chunk), thus the receiving of query result can take quite a long time.

One possibility to improve this is to use ORDER BY and LIMIT in your queries. By doing this you can order your result records, e.g. by Id, and use the biggest Id (if you use ascending order) as additional condition in your next query. This approach has the advantage that you will have well defined amount of records returned and nearly the same execution time for each query.