1

I have been trying to create CurrencyType records from APEX and since that doesn't support DML, have been using the REST endpoint and POST method. Everything work fine with single record but with multiple records, I am getting this error:

[ { "message": "Json Deserialization failed on token 'null' and has left off in the middle of parsing a row. Will go to end of row to begin parsing the next row", "errorCode": "INVALID_FIELD" } ]

I don't see how the code worked for single object, if it really were an Invalid Field.

I have seen this and this but have been unable to fix my issue.

Here is my code:

public static void syncCurrencyTypeTableMultiple(){
    Http h = new Http();
    HttpRequest req = new HttpRequest();
    req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm() + '/services/data/v41.0/sobjects/CurrencyType/');
    req.setHeader('Authorization', 'OAuth ' + UserInfo.getSessionId());
    req.setHeader('Content-Type', 'application/json');
    req.setMethod('POST');

    List<CurrencyType> currTypeList = new List<CurrencyType>();

    for(sanmgdpack__PST_Currency__c curr: [Select sanmgdpack__ISO_Code__c, sanmgdpack__Conversion_Rate__c, sanmgdpack__Decimal_Places__c FROM sanmgdpack__PST_Currency__c]) {
        CurrencyType currTypeObj = new CurrencyType(
                                            IsoCode = curr.sanmgdpack__ISO_Code__c, 
                                            ConversionRate = curr.sanmgdpack__Conversion_Rate__c, 
                                            DecimalPlaces = Integer.valueOf(curr.sanmgdpack__Decimal_Places__c)
                                            );
        currTypeList.add(currTypeObj);
    }

    String jsonStr = JSON.serializePretty(currTypeList);
    System.debug('json Str:' + jsonStr);


    //test
    //List<CurrencyType> deserList = (List<CurrencyType>)JSON.deserialize(jsonStr, List<CurrencyType>.class);

    //System.debug('deserlist::::' + deserList); //works fine

    req.setBody(jsonStr);
    System.debug(req);
    HttpResponse res = h.send(req);
    System.debug(res);
}
  • Thinking that wrapper class was causing the problem, I removed it altogether. (edited my code - current code has no wrapper) Even then same issue persists. Please could someone help me? Is SFDC support for multiple object creation through REST having a bug? – SFDC Dev 27 Dec 5 '17 at 16:02
  • you are trying to insert multiple CurrencyType records in a single REST call? If so, you need to use the REST Composite Batch API that has some limitations. There is an excellent discussion on options in this blog post – cropredy Dec 6 '17 at 1:43
  • thanks a lot, you can put it as an answer so that I can choose that! – SFDC Dev 27 Dec 6 '17 at 13:02
  • glad this worked for you – cropredy Dec 6 '17 at 16:43
1

The SFDC REST API for Create-Update-Delete operations only work on single records. To address this, SFDC added a Composite Resource feature that allows:

  • inserting multiple unrelated objects (your use case)
  • inserting a tree of objects (e.g. Account and its child Contacts)
  • inserting an object, then using its values to insert/update another object

and more. See the REST API documentation on Composite resources

For multiple CurrencyType (max 200)

https://yourInstance.salesforce.com/services/data/v41.0/composite/tree/CurrencyType/

with POST body:

{
"records" :[{
    "attributes" : {"type" : "CurrencyType", "referenceId" : "ref11"},
    "IsoCode": "USD",
    "DecimalPlaces": 2,
    "ConversionRate": 1.3   
    },{
    "attributes" : {"type" : "CurrencyType", "referenceId" : "ref22"},
    "IsoCode": "CHF",
    "DecimalPlaces": 2,
    "ConversionRate": 1.5
    },
    ...
   ]
}

The referenceId should be unique and are used to assist you in correlating the REST Response body to see which rows failed to insert.

There is a superb discussion in Daniel Ballinger's blog on bulk updating from an API that is well worth reading

1

Thanks a lot cropredy, your post directed me to the right direction.

I have managed to get it working using REST Composite Tree same as this SF Doc example

Here are the request details:

endpoint: https://na73.salesforce.com/services/data/v41.0/composite/tree/CurrencyType/ auth: Bearer

JSON Body:

    {
"records" :[{
    "attributes" : {"type" : "CurrencyType", "referenceId" : "ref11"},
    "IsoCode": "AFN",
    "DecimalPlaces": 6,
    "ConversionRate": 1.5   
    },{
    "attributes" : {"type" : "CurrencyType", "referenceId" : "ref22"},
    "IsoCode": "ALL",
    "DecimalPlaces": 6,
    "ConversionRate": 1.5
    },{
    "attributes" : {"type" : "CurrencyType", "referenceId" : "ref33"},
    "IsoCode": "AMD",
    "DecimalPlaces": 6,
    "ConversionRate": 1.5
    },{
    "attributes" : {"type" : "CurrencyType", "referenceId" : "ref44"},
    "IsoCode": "ANG",
    "DecimalPlaces": 6,
    "ConversionRate": 1.5
    }]
}
0

I had a similar issue, and discovered it was a problem with my client. I was producing JSON directly to a String, and giving the String to Jackson to produce JSON. Jackson encodes it, with the result that you get invalid JSON: the quotes around the field names get escaped:

\"myField\" : 123

instead of

"myField" : 123

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.