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]