0

We have 2 objects : Order_Integration__c, Order. We are running the batch Copying order integration table data to order table.

Requirement : If any error occurs while creating order. That respective Error Information, need to capture under respective "Order Integration Table". Order Integration and order Linked through External Id.

For Doing that : I had written below Logic :

Code Snippet:

for (Database.upsertResult res : lsr) {  //Lsr is  inserted orderList
                for(order ord:upsertOrderList){ //Lsr is complete 
orderIntegrtaion TableList
                   if (res.isSuccess()) {
                        
                    }
                    else{
                       
                        for(Database.Error err : res.getErrors()){
                        
                           error+= err.getStatusCode() + ': ' + err.getMessage();
                            error+= 'Fields: '+err.getFields();
                            error+='\n';
                             Order_Integration__c ordInt = new Order_Integration__c();
                            ordInt.Id=ord.Order_Integration_Ids__c;
                            ordInt.Status_Description__c = error;
                            ordIntegrationList.add(ordInt);
                }
                }
                }
                }
                
    

Exception Received:

              System.LimitException: Apex heap size too large: 17542735.

Seems Like Its because of for with for Loop Iteration. If I avoid ,for within for how can I achieve this requirement.

Completed Code:

for(Order_Integration__c ord:scope){
     order ord = new order();
     ord.Order_Integration_Ids__c = orderIntegrate.Id;
         --- so on -----
     upsertOrderList.add(ord);
  }

 //Upsert orderList -> creating OrderRecord List

   if (upsertOrderList.size() > 0) {
            Database.upsertResult[] lsr = 
  Database.upsert(upsertOrderList,order.fields.External_Id__c,false);
            Integer recordid = 0;
            error = '';
            integer count = 0;
            for (Database.upsertResult res : lsr) {
                for(order ord:upsertOrderList){
                    if (res.isSuccess()) {
                        if(res.isCreated()){
                            successRecCount++;  
                        }
                        orderIdSet.add(res.getId());
                    }
                    else{
                        hasErrors = true;
                        for(Database.Error err : res.getErrors()){
                             errorRecCount++;
                            Order_Integration__c ordInt = new Order_Integration__c();
                            ordInt.Id=ord.Order_Integration_Ids__c;
                            error+= err.getStatusCode() + ': ' + err.getMessage();
                            error+= 'Fields: '+err.getFields();
                            error+='\n';
                            ordInt.Status_Description__c = error;
                            ordIntegrationList.add(ordInt);
                            if(err.getStatusCode() == system.StatusCode.REQUIRED_FIELD_MISSING){
                                if(errorMap.containsKey(err.getMessage())){
                                    count = errorMap.get(err.getMessage());
                                    errorMap.put(err.getMessage(),++count);
                                }else{
                                    errorMap.put(err.getMessage(),1);
                                }
                            }
                            
                        }
                    }
                }
                
            }
        }
        
        
        if(!ordIntegrationList.isempty()){
            map<id,Order_Integration__c> errorDescriptionMap = new map<id,Order_Integration__c>();
            //put all the values from the list to map. 
            errorDescriptionMap.putall(ordIntegrationList);
            if(errorDescriptionMap.size()>0){
                update errorDescriptionMap.values();
            }
        }
1
  • 2
    Shouldn't you error = '' be inside for(order ord:upsertOrderList){ as you are creating Order_Integration__c object while iterating upsertOrderList. Basically the issue is you String error is going beyond 12MB limit. – Nagendra Singh Dec 1 '20 at 3:24
2

First your core logic of checking if a record is success or not is incorrect. . As it will always create junk Order_Integration__c records for each upsertOrderList.

As per your code lets say if first result in lsr is not successful, so the code will go ahead iterate on all upsertOrderList and create Order_Integration__c records for all upsertOrderList in else condition.

For checking if a upsert has passed successfully or not check this

As explained here order of the result and the upsert records will be always same.

for (Integer index = 0; index < lsr.size(); index++) {
    error = '';
    errorRecCount = 0;
    if(lsr[index].isSuccess() && lsr[index].isCreated()){
        if (lsr[index].isCreated()) {
            successRecCount++;
        }
        orderIdSet.add(lsr[index].getId());
    } else {
        hasErrors = true;
        for (Database.Error err : lsr[index].getErrors()) {
            errorRecCount++;
            Order_Integration__c ordInt = new Order_Integration__c();
            ordInt.Id = upsertOrderList[index].Order_Integration_Ids__c;
            error += err.getStatusCode() + ': ' + err.getMessage();
            error += 'Fields: ' + err.getFields();
            error += '\n';
            ordInt.Status_Description__c = error;
            ordIntegrationList.add(ordInt);
            if (err.getStatusCode() == system.StatusCode.REQUIRED_FIELD_MISSING) {
                if (errorMap.containsKey(err.getMessage())) {
                    count = errorMap.get(err.getMessage());
                    errorMap.put(err.getMessage(), ++count);
                } else {
                    errorMap.put(err.getMessage(), 1);
                }
            }
        }
    }
}

For the exception , I believe you are initializing error = '' and errorRecCount in wrong place. It should be inside the for loop like shown above.

The issue is as you have initialized String at top and concatenating it always, so there might be scenario in your batch where that String is growing beyond 12MB of heap limit.

4
  • error issue resolved by mistake added that complete error code. how to resolve that mapping order and order integration failed record issue? – Annappa Dec 1 '20 at 4:26
  • concantenate string causing that issue..understood. how to resolve maping issue – Annappa Dec 1 '20 at 4:28
  • Its explained beautifully by @sfdcfox in the link i have given above, but also sharing an example in above snippet. – Nagendra Singh Dec 1 '20 at 4:39
  • Thanks Nagendra – Annappa Dec 1 '20 at 5:36

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.