1

I am trying to insert json data in to salesforce objects. Json string is too large so i am using batch apex to insert data. For this I had written apex class i didn't got any error But records not inserted in to salesforce. so please check my code below. and tell me what i was doing wrong?

global class CustomerRecordsCtrl implements Database.Batchable<sObject>{
    String query;

    global Database.querylocator start(Database.BatchableContext BC){
        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, List<Customer__c> scope)
    {
        HttpRequest req= new HttpRequest();
        Http http = new Http();
        req.setMethod('GET');

        String url = 'http://iprocureafrica.co/index.php/restApi/customer_c/3';
        req.setEndpoint(url);

        HttpResponse res = http.send(req);
        String json =  res.getBody().replace('\n','');

        parseJSON(json);
    }

    public List<WrapperClass> wrappers{get;set;}

    public void parseJSON(String jsonstr){
        if (jsonstr != null){
            wrappers= new List<WrapperClass>();
            JSONParser parser = JSON.createParser(jsonstr);
            while (parser.nextToken() != null) {
                if (parser.getCurrentToken() == JSONToken.START_ARRAY) {
                    while (parser.nextToken() !=  JSONToken.END_ARRAY) {
                        if (parser.getCurrentToken() == JSONToken.START_OBJECT) {
                            WrapperClass ci = new WrapperClass();
                            while (parser.nextToken() !=  JSONToken.END_OBJECT) {
                                if((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&(parser.getText().tolowercase() == 'id')){
                                    parser.nextToken();
                                    ci.id = parser.getText();
                                }
                                [... snipped out bunch of ifs ...]
                            }
                            wrappers.add(ci);
                            List<Customer__c> InsrtRecord = new List<Customer__c>();  // object list

                            for(WrapperClass wc:wrappers)  {
                                Customer__c shp = new Customer__c ();   // object instance with memory allocation.
                                // field mapping
                                shp.Customer_ID__c = Decimal.valueOf (wc.id);
                                shp.Name= wc.name;
                                shp.Company_Name__c = wc.companyname;
                                shp.Mobile_Number__c = wc.phone;

                                shp.Customer_Code__c = Decimal.valueOf(wc.customercode);
                                shp.Agent__c = Decimal.valueOf(wc.agent);
                                shp.Supplier__c = Decimal.valueOf (wc.supplier);
                                shp.Date_of_Registration__c = Date.valueOf(wc.dateofreg);
                                shp.Status__c = wc.status;
                                shp.Geocode__c = Decimal.valueOf(wc.geocode);
                                shp.Type__c = Decimal.valueOf(wc.type);
                                shp.Salesforce_Status__c = wc.salesforcestatus;
                                shp.National_ID__c = Decimal.valueOf(wc.nationalid);

                                InsrtRecord.add(shp); // add to list

                                If(InsrtRecord .size() > 0 ) // check list size
                                {
                                    upsert shp ; // insert list.
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    public class WrapperClass{
        public string id {get;set;}
        public string name {get;set;}
        public string companyname{get;set;}
        public string phone{get;set;}
        public string customercode{get;set;}
        public string agent{get;set;}
        public string supplier{get;set;}
        public string dateofreg{get;set;}
        public string status{get;set;}
        public string geocode{get;set;}
        public string type{get;set;}
        public string salesforcestatus{get;set;}
        public string nationalid{get;set;}
        public string date1{get;set;}

        public WrapperClass(){ }
    }

    global void finish(Database.BatchableContext BC){ }

    public PageReference GoToInsert() {
        return null;
    }
}
  • 2
    Hi Nayana, welcome to the site. You have not provided enough information for anyone to provide a meaningful answer to your question. Can you edit your question to provide as much information as possible, including code. – BarCotter Oct 13 '14 at 9:54
  • Could you please enable debug logs and publish more details about the issue? – Marcin Sz. Oct 13 '14 at 10:04
  • Posting the code could help – Prady Oct 13 '14 at 10:56
  • First of all, you cannot do callouts from the execute method of the batch, unless you also add implements Database.AllowsCallouts to your class definition. Furthermore, your logic seems to be flawed, as the parseJSON methods has a for loop within 3 whiles that contains a DML call. You probably want to put the for loop beneath the outer while. – rael_kid Oct 13 '14 at 13:30
1

The Batch is iterating over Customer__c instead of the result of the REST callout. Since you are creating new records for Customer__c, there is nothing available to the start() method to query and iterate over.

So basically the start method needs to call the REST endpoint and parse the results into an iterable datastructure. The execute method would then iterate over chunks of this data, convert it into Customer__c records and insert them into the database.

This would only work, if the result of the REST call and its parsing will not reach any limits (Heap size, Processing time). Otherwise the REST endpoint needs to be changed to serve chunks of data.

So a basic outline of a batch could look like the following:

public virtual class BatchCustomerRecordsCreator
    implements Database.Batchable, Database.AllowsCallouts {

    public Database.QueryLocator start(Database.BatchableContext BC) {
        String jsonString = getJSONFromREST();

        return (List<Map<String, Object>>) JSON.deserialize(jsonString, List<Map<String, Object>>.class);
    }

    public void execute(Database.BatchableContext BC, List<Map<String, Object>> records) {
        List<Customer__c> customers = new List<Customer__c>();

        for (Map<String, Object> record : records) {
            customers.add(
                buildCustomer(record)
            );
        }

        insert customers;
    }

    public void finish(Database.BatchableContext BC){}

    @TestVisible
    private virtual Customer__c buildCustomer(Map<String, Object> record) {
        return new Customer__c(
            Name = (String) record.get('Name'),
            Customer_ID__c = (Decimal) record.get('Id')

        );
    }

    @TestVisible
    private virtual String getJSONFromREST() {
        HttpRequest req= new HttpRequest();
        req.setMethod('GET');

        String url = 'http://iprocureafrica.co/index.php/restApi/customer_c/3';
        req.setEndpoint(url);

        HttpResponse res = http.send(req);
        return res.getBody();
    }
}
| improve this answer | |

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.