1

I have a batch class which basically does a soql of to get a list of account records. In the execute, i want to get the list returned and pass them to a Http callout function which will do a Post request to insert the list into another org. If I run:

moveObjectsToNewOrg b = new moveObjectsToNewOrg();
Database.executeBatch(b, 50);

i get a callout response of: System.HttpResponse[Status=Server Error, StatusCode=500]

However, when i try:

Account acct1 = new Account(Name='Dummy 1');  
Account acct2 = new Account(Name='Dummy 2');  
List<Account> accList = new List<Account>{acct1, acct2};
submitDataToTargetOrg.submitDataUsingRest(accList);

it works perfectly with a statuscode 200. Here is what my batch class looks like :

global class moveObjectsToNewOrg implements Database.Stateful, Database.Batchable<sObject>, Database.AllowsCallouts{

    public Database.QueryLocator start(Database.BatchableContext context){
        if (LOG_THIS_CLASS) System.debug('starting batch.. : ' + context);
        return Database.getQueryLocator('SELECT Id, Name FROM Account WHERE Name LIKE \'Dummy%\'');
    }

    public void execute(Database.BatchableContext context, List<SObject> scope){
        submitDataToTargetOrg.submitDataUsingRest((List<Account>)scope);
    }

    public Void finish(Database.BatchableContext context){}
    }

I call this function which is outside of the batch class:

public static HttpRequest submitDataUsingRest(List<SObject> recordsToTransfer) {
    Schema.SObjectType sObjectType = recordsToTransfer.getSObjectType();
        HttpRequest req;
        if (sObjectType != null){
            String listType = 'List<' + sObjectType + '>';
            List<SObject> castRecords = (List<SObject>)Type.forName(listType).newInstance();
            castRecords.addAll(recordsToTransfer);
            String reqbody = 'grant_type=password&client_id='+clientId+'&client_secret='+clientSecret+'&username='+userName+'&password='+password;

            Http http = new Http();
            req = new HttpRequest();
            req.setBody(reqbody);
            req.setMethod('POST');
            req.setEndpoint('https://eu6.salesforce.com/services/oauth2/token');

            HttpResponse res = http.send(req);
            OAuth2 objAuthenticationInfo = (OAuth2)JSON.deserialize(res.getbody(), OAuth2.class);

            if(objAuthenticationInfo.access_token!=null){
                String requestBody = '{"req":{"accounts":'+JSON.serialize(castRecords)+'}}';
                Http http2 = new Http();
                HttpRequest req1 = new HttpRequest();
                string endP = 'https://eu6.salesforce.com/services/apexrest/getAccountData';
                req1.setHeader('Authorization','Bearer ' + objAuthenticationInfo.access_token);
                req1.setHeader('Content-Type','application/json');
                req1.setMethod('POST');
                req1.setBody(requestBody);
                req1.setEndpoint(endP);
                if (LOG_THIS_CLASS) System.debug('end point : ' + req1.getEndpoint());
                if (LOG_THIS_CLASS) System.debug('end point : ' + req1.getBody());
                HttpResponse res1 = http2.send(req1);
            }
        }

And in the target org, I just do a simple function to insert the parsed Accounts:

@RestResource(urlmapping = '/getAccountData/*')
global  class accountRestService {

    PRIVATE STATIC FINAL BOOLEAN LOG_THIS_CLASS = TRUE;

    global class requestBody {
        global List<Account> accounts;
   }

    @httpPost
    global static List<Account> populateAccountObject(accountRestService.requestBody req){
        if (LOG_THIS_CLASS) System.debug('the request in populateAccountObject.. : ' + req);
        insert req.accounts;
        return req.accounts;
    }
}

To me, it only looks as though there's a problem when inserting the records before doing the callout as i tried in the Anonymous window. Any help pls. thx

Edit: Actually i get the following error in the target org:

Insert field: First exception on row 0 with id 00158000004kohAAE; first error: INVALID_FIELD_FOR_INSERT_UPDATE, cannot specify Id in an insert call:[Id]
1
  • 2
    You are doing an insert in the target org but you are including the id from the source org in the data and so your insert is failing. In your target remove the id from the data set. You may want to think about stopping duplicates and possibly use the source id as a unique identifier. – Richard Durrant Apr 14 '16 at 12:52
0

It appears to me that based on what you know works, you'd need to do something like this in your execute method:

List<Account> accList = new List<Account>();
for( scope Account a:sObject){ 
   accList.add(a);
}

submitDataToTargetOrg.submitDataUsingRest(accList);

In essence, for the scope, you've not cast the list of sObjects to Accounts yet in your previous code.

0

actually, all i had to do was change the logic a bit in my target org to create a new account i.e. :

@httpPost
global static List<Account> populateAccountObject(accountRestService.requestBody req){
    List<Account> accountsToInsert = new List<Account>();
    Account newAccount;
    for(Account acc : req.accounts){
        newAccount = new Account(Name = acc.Name, Phone = acc.Phone);
        accountsToInsert.add(newAccount);
    }
    insert accountsToInsert;
    return accountsToInsert;
}

}

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.