You need to sign in to do that
Don't have an account?
steve456
Apex heap size too large: 5218807
I am facing this issue.Can anybody help me out?
"
Update error code CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY: ReconcileOrder: execution of BeforeUpdate caused by: System.Exception: Apex heap size too large: 5218807
"
The trigger that is executing is consuming too much memory. You are limited to 6 MB of memory per transaction.
Without more information it's hard to give more details, but some things to look for:
1. Recursive Triggers - Triggers firing more times than needed. Checkout the Force.com Cookbook Recipe to see how to resolve.
2. More fields than necessary in SOQL - If you are using SOQL in your triggers, its possible you are returning more fields than necessary.
I will post the trigger corresponding to the issue.Can you help me in addressing the issue
trigger ReconcileOrder on Order_2020__c (before update) {
//clean phone numbers
for(Order_2020__c o:System.Trigger.new)
{
if(o.BTN_Client__c!=null)
{
o.BTN_Client__c=DateStringUtility.cleanPhoneNumber(o.BTN_Client__c);
}
if(o.BTN__c!=null)
{
o.BTN__c=DateStringUtility.cleanPhoneNumber(o.BTN__c);
}
}
List<Order_2020__c> orderList=new List<Order_2020__c>();
Set<String> btnList=new Set<String>();
Set<String> firstNameList=new Set<String>();
Set<String> lastNameList=new Set<String>();
Set<String> zipCodeList=new Set<String>();
Map <Id, String> newNamesList = new Map <Id, String>();
for(Order_2020__c o:System.Trigger.new) {
newNamesList.put(o.Id, o.Name);
}
// Get List of all the Names that matches in the System
System.debug('*******************ReconcileOrder - Query 1************');
Order_2020__c[] oDuplicateList = [SELECT Id, Name FROM Order_2020__c o
WHERE o.Name IN :newNamesList.values()];
//get a list of orders that match the criteria
for(Order_2020__c o:System.Trigger.new)
{
Order_2020__c oOld = Trigger.oldMap.get(o.Id);
//----New Code Change Key on Order and on Order Detail when Order Number is changed
if (o.Name != oOld.Name ) {
OrderUtility orderUtil = new OrderUtility();
orderUtil.changeOrderNumber(newNamesList, oDuplicateList, o, oOld );
} // Old Order Number is different from the new one
if(o.Reconcile__c && !o.Locked__c)
{
//add the order to valid order list
orderList.add(o);
//add the BTN to btn list to be used to get old orders matching the currnt one
if(o.BTN_Client__c!=null)
{
if(DateStringUtility.cleanPhoneNumber(o.BTN_Client__c)!='9999999999' &&
DateStringUtility.cleanPhoneNumber(o.BTN_Client__c)!='1000000000')
{
btnList.add(o.BTN_Client__c);
if(DateStringUtility.getFormatttedPhoneNumber(o.BTN_Client__c)!=null)
{
btnList.add(DateStringUtility.getFormatttedPhoneNumber(o.BTN_Client__c));
}
}
}
if(o.First_Name_Client__c!=null)
{
firstNameList.add(o.First_Name_Client__c);
}
if(o.Last_Name_Client__c!=null)
{
lastNameList.add(o.Last_Name_Client__c);
}
if(o.Cust_Zip__c!=null)
{
zipCodeList.add(o.Cust_Zip__c);
}
//reset the reject reason
o.Reject_Reason__c=null;
}
o.Reconcile__c=false;
}
//process orders
if(orderList.size()>0)
{
//get order details
System.debug('*******************ReconcileOrder - Query 2************');
Order_Entry__c[] orderDetails=new Order_Entry__c[0];
orderDetails=[Select Id, Order_Number__c, Status__c,Self_Status__c,Product__c,
Order_Type__c,Order_Type_Client__c,Product_Group__c
from Order_Entry__c where Order_Number__c in : orderList];
Map<Id,List<Order_Entry__c>> orderDetailMap=new Map<Id,List<Order_Entry__c>>();
Map<Id,List<Order_Entry__c>> orderDetailNonCompMap=new Map<Id,List<Order_Entry__c>>();
//prepate order detail map
for(Order_Entry__c oe:orderDetails)
{
//add to non-comp map
if('Non-Comp'.equalsIgnoreCase(oe.Status__c))
{
if(orderDetailNonCompMap.get(oe.Order_Number__c)==null)
{
orderDetailNonCompMap.put(oe.Order_Number__c,new List<Order_Entry__c>{oe});
}
else
{
orderDetailNonCompMap.get(oe.Order_Number__c).add(oe);
}
}
//add to regular map
else
{
if(orderDetailMap.get(oe.Order_Number__c)==null)
{
orderDetailMap.put(oe.Order_Number__c,new List<Order_Entry__c>{oe});
}
else
{
orderDetailMap.get(oe.Order_Number__c).add(oe);
}
}
}
Map<Id,Order_2020__c> oldOrderMap=new Map<Id,Order_2020__c>();
//get old orders matching new orders by BTN
System.debug('*******************ReconcileOrder - Query 3************');
List<Order_2020__c> oldOrderBtnList=new List<Order_2020__c>();
if(btnList.size()>0)
{
oldOrderBtnList=[Select Name, BTN__c, BTN_Client__c, Cust_City__c, Cust_State__c,
Cust_Zip__c, First_Name_Client__c, Id, Last_Name_Client__c,Date_Client__c from Order_2020__c
where BTN_Client__c!=null and BTN_Client__c in : btnList];
System.debug('Old orders matching by btn: '+oldOrderBtnList.size());
}
//update general old order map
for(Order_2020__c o :oldOrderBtnList)
{
if(oldOrderMap.get(o.Id)==null)
{
oldOrderMap.put(o.Id,o);
}
}
//create a map of old orders by btn
Map<String, List<Order_2020__c>> oldOrderBtnMap=new Map<String, List<Order_2020__c>>();
for(Order_2020__c o :oldOrderBtnList)
{
String formattedPhone=DateStringUtility.cleanPhoneNumber(o.BTN_Client__c);
if(oldOrderBtnMap.get(formattedPhone)==null)
{
oldOrderBtnMap.put(formattedPhone,new List<Order_2020__c>{o});
}
else
{
oldOrderBtnMap.get(formattedPhone).add(o);
}
}
//get old orders matching new orders by lastname, firstname and zip
System.debug('*******************ReconcileOrder - Query 4************');
List<Order_2020__c> oldOrderClientList=[Select Name, BTN__c, BTN_Client__c, Cust_City__c, Cust_State__c,
Cust_Zip__c, First_Name_Client__c, Id, Last_Name_Client__c,Date_Client__c from Order_2020__c where
Cust_Zip__c in : zipCodeList and First_Name_Client__c in:firstNameList and Last_Name_Client__c in :lastNameList];
//update general old order map
for(Order_2020__c o :oldOrderClientList)
{
if(oldOrderMap.get(o.Id)==null)
{
oldOrderMap.put(o.Id,o);
}
}
//create a map of old orders by client
Map<String, List<Order_2020__c>> oldOrderClientMap=new Map<String, List<Order_2020__c>>();
for(Order_2020__c o :oldOrderClientList)
{
String clientKey=o.First_Name_Client__c.toUpperCase()+'-'+o.Last_Name_Client__c.toUpperCase()+'-'+o.Cust_Zip__c.toUpperCase();
if(oldOrderClientMap.get(clientKey)==null)
{
oldOrderClientMap.put(clientKey,new List<Order_2020__c>{o});
}
else
{
oldOrderClientMap.get(clientKey).add(o);
}
}
//get order details for old orders
//non comp order details should not be considered as per Mark
System.debug('*******************ReconcileOrder - Query 5************');
Order_Entry__c[] oldOrderDetails=[Select Id, Order_Number__c, Status__c,Self_Status__c,
Product__c,Product_Group__c from Order_Entry__c
where Status__c!='Non-Comp' and
(Order_Number__c in : oldOrderClientList or Order_Number__c in : oldOrderBtnList)];
Map<Id,List<Order_Entry__c>> oldOrderDetailMap=new Map<Id,List<Order_Entry__c>>();
//prepate order detail map
for(Order_Entry__c oe:oldOrderDetails)
{
if(oldOrderDetailMap.get(oe.Order_Number__c)==null)
{
oldOrderDetailMap.put(oe.Order_Number__c,new List<Order_Entry__c>{oe});
}
else
{
oldOrderDetailMap.get(oe.Order_Number__c).add(oe);
}
}
List<Order_Entry__c> updatedOrderDetails=new List<Order_Entry__c>();
//process each order marked for Reconcile
for(Order_2020__c o:orderList)
{
String rejectReason='';
boolean orderReconciled=true;
Integer deniedCount=0;
Integer compOECount=0;
//check if header is matched
if(o.Self_Status__c!='Matched')
{
orderReconciled=false;
rejectReason+='Header not Matched ; ';
}
//order that doesn't have comp as well as non-comp products is rejected
if(orderDetailMap.get(o.Id)==null && orderDetailNonCompMap.get(o.Id)==null)
{
o.Status__c='Rejected';
rejectReason+='No Products Ordered';
o.Reject_Reason__c=rejectReason;
orderReconciled=false;
}
//has comp products
else if(orderDetailMap.get(o.Id)!=null)
{
List<Order_Entry__c> currentDetails=orderDetailMap.get(o.Id);
compOECount=currentDetails.size();
//check if all order details are matched
boolean detailsMatched=true;
for(Order_Entry__c coe:currentDetails)
{
boolean orderEntryReconciled=true;
//reset status flags
coe.Reject_Reason__c=null;
coe.Status__c=null;
if(coe.Self_Status__c!='Matched')
{
orderReconciled=false;
detailsMatched=false;
orderEntryReconciled=false;
coe.Status__c='Rejected';
}
else if(ConvertSalesTracker.ProductGroupWithOrderTypeReconciliation(coe.Product_Group__c))
{
if(coe.Order_Type__c!=coe.Order_Type_Client__c)
{
orderReconciled=false;
detailsMatched=false;
orderEntryReconciled=false;
coe.Status__c='Rejected';
coe.Reject_Reason__c='Order Type Not Matched';
}
else
{
if(coe.Order_Type__c==null)
{
orderReconciled=false;
detailsMatched=false;
orderEntryReconciled=false;
coe.Status__c='Rejected';
}
else
{
if(coe.Order_Type__c=='Upgrade' || coe.Order_Type__c=='Downgrade')
{
coe.Status__c='Denied';
deniedCount++;
}
}
}
}
if(orderEntryReconciled && coe.Status__c!='Denied')
{
coe.Status__c='Matched';
}
//add order entry to the list
updatedOrderDetails.add(coe);
}
if(detailsMatched==false)
{
rejectReason+='Product not Matched ; ';
}
//check duplicate orders
boolean dupFound=false;
Set<Id> dupOrderList=new Set<Id>();
String clientKey=null;
if(o.First_Name_Client__c!=null && o.Last_Name_Client__c!=null && o.Cust_Zip__c!=null)
{
clientKey=o.First_Name_Client__c.toUpperCase()+'-'+o.Last_Name_Client__c.toUpperCase()+'-'+o.Cust_Zip__c.toUpperCase();
}
String formattedPhone=DateStringUtility.cleanPhoneNumber(o.BTN_Client__c);
//check duplicate by btn
if(oldOrderBtnMap.get(formattedPhone)!=null && formattedPhone!='1000000000' && formattedPhone!='9999999999')
{
List<Order_2020__c> currentDupBtnOrders=oldOrderBtnMap.get(formattedPhone);
for(Order_Entry__c coe:currentDetails)
{
for(Order_2020__c dupBtnOrder:currentDupBtnOrders)
{
if(oldOrderDetailMap.get(dupBtnOrder.Id)!=null && dupBtnOrder.Id!=o.Id)
{
List<Order_Entry__c> currentDupBtnOrderDetails= oldOrderDetailMap.get(dupBtnOrder.Id);
for (Order_Entry__c dupBtnOrderEntry:currentDupBtnOrderDetails)
{
if(dupBtnOrderEntry.Product__c==coe.Product__c)
{
dupFound=true;
dupOrderList.add(dupBtnOrder.Id);
break;
}
}
}
}
}
}
//check duplicate by client
if(oldOrderClientMap.get(clientKey)!=null)
{
List<Order_2020__c> currentDupClientOrders=oldOrderClientMap.get(clientKey);
for(Order_Entry__c coe:currentDetails)
{
for(Order_2020__c dupClientOrder:currentDupClientOrders)
{
if(oldOrderDetailMap.get(dupClientOrder.Id)!=null && dupClientOrder.Id!=o.Id)
{
List<Order_Entry__c> currentDupClientOrderDetails= oldOrderDetailMap.get(dupClientOrder.Id);
for (Order_Entry__c dupClientOrderEntry:currentDupClientOrderDetails)
{
if(dupClientOrderEntry.Product__c==coe.Product__c)
{
dupFound=true;
dupOrderList.add(dupClientOrder.Id);
break;
}
}
}
}
}
}
if(dupFound && !o.Allow_Dupe__c)
{
orderReconciled=false;
rejectReason+='Possible Dupes: ';
Date maxDate=null;
String maxOrderName=null;
Id maxOrderId=null;
for(Id dupId:dupOrderList)
{
Order_2020__c cOrder=oldOrderMap.get(dupId);
rejectReason+=cOrder.Name+', ';
if(maxDate==null && cOrder.Date_Client__c!=null)
{
maxDate=cOrder.Date_Client__c;
maxOrderName=cOrder.Name;
maxOrderId=dupId;
}
else if(maxDate!=null && cOrder.Date_Client__c!=null)
{
if(cOrder.Date_Client__c>maxDate)
{
maxDate=cOrder.Date_Client__c;
maxOrderName=cOrder.Name;
maxOrderId=dupId;
}
}
}
if(maxDate!=null)
{
o.Dupe_ID__c=maxOrderId;
o.Dupe_Name__c= maxOrderName;
}
}
else
{
o.Dupe_ID__c=null;
o.Dupe_Name__c= null;
}
if(orderReconciled)
{
//update the order
//if all order entrees are denied, set order status to non-comp
if(deniedCount==compOECount)
{
o.Status__c='Non-Comp';
}
else
{
o.Status__c='Matched';
}
o.Reject_Reason__c=null;
}
else
{
o.Status__c='Rejected';
if(rejectReason.endsWith(', '))
{
rejectReason=rejectReason.substring(0,rejectReason.length()-2);
}
o.Reject_Reason__c=rejectReason;
}
}
//order has only non comp products
else
{
if(orderReconciled==true)
{
o.Status__c='Non-Comp';
}
else
{
o.Status__c='Rejected';
o.Reject_Reason__c=rejectReason;
}
}
}//end of process each order marked for Reconcile
//update if there are any order details in the bucket
if(updatedOrderDetails.size()>0)
{
update updatedOrderDetails;
}
}//end of process orders
}
If u see my trigger
I am making an update on the before update
Will this cause to be self recursive
It doesn't look as though it should be from this, you're not updating the Order_2020__c object, just Order_Entry__c records. That said - are there any triggers on Order_Entry__c that would cause an update to an Order_2020__c?
If cascading triggers isn't the problem, then you probably need to concentrate on using fewer maps/lists, or at least clearing them when you no longer need them so that they free up used memory.
Matt the error is pointing to this line
"oldOrderDetailMap.get(oe.Order_Number__c).add(oe);"
That just happens to be the point where you're running out of memory on the heap to work with. Look through the code and release collections once you no longer need them, for instance, after the query here:
You could then clear the lists of first and last names because they're not used (maybe setting them to null would be better, though I don't know how the garbage collection works).
And after this part:
You could release that orderList. Where you might come unstuck is if doing these things doesn't release any space on the heap, if that's the case I'd suggest using your trigger to execute a batch apex class (moving your code into it), running it with a batch size of 1 so that each Order_2020___c record is processed at a time. For each one you' get a fresh run on the governor limits which should help alleviate your problems.
could you help me in modifyng d code???
This error comes due to huge use of memory. Now to resolve this issue, you have to make memory free after it's use.
Like if we take one list of your code:
List<Order_2020__c> orderList=new List<Order_2020__c>();
after performing the various function by orderlist. Make orderlist = null. Do same thing for other list,set and map.
It will resolve the heap error.
Please mark as a solution,so that it will benefit others.
Thanks
Could you help me in making the change to the code