function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
SHRUTI HASILKAR 8SHRUTI HASILKAR 8 

System.LimitException: Apex heap size too large: 67116041

Hi

I am getting "System.LimitException: Apex heap size too large: 67116041" error. Please find my below piece of code.

public static void checkC4StageLA(List<Account> accountList, Map<id,Account> oldMap){
        Transient Integer count = 0;
        List<Opportunity> oppList = new List<Opportunity>();
        
        system.debug('accountList '+accountList); 
        List<Account> accList = new List<Account>();
        Map<ID, List<Opportunity>> oppMap = new Map<ID, List<Opportunity>>();
        
        oppList = [SELECT ID, Name, AccountID, stageName FROM Opportunity WHERE AccountID IN : accountList];
         
         system.debug('accountList '+accountList); 
         if(oppList.size() > 0){
            List<Opportunity> tempOppList = new List<Opportunity>();
            for(Opportunity opp: oppList){ //Reason behind to write Query in for loop is: To avoid heap size limit exception.
                if(oppMap.containsKey(opp.AccountID)){
                    tempOppList.addAll(oppMap.get(opp.AccountID));    
                }
                tempOppList.add(opp);
                oppMap.put(opp.AccountID, tempOppList);    
            }
            
          }
          
          List<Profile> PROFILE = [SELECT Id, Name FROM Profile WHERE Id=:userinfo.getProfileId() LIMIT 1];
          String MyProflieName = PROFILE[0].Name;
          system.debug('MyProflieName  '+MyProflieName );
          
          for(Account acc: accountList){
              if(oppMap.containsKey(acc.ID) && oppMap.get(acc.ID).size() > 0){
                  for(Opportunity opp: oppMap.get(acc.ID)){
                      if(opp.stageName == 'C4- Payment Disbursed'){
                          System.debug('ID '+opp.ID);
                          count++;    
                      }
                  }
              }    
              
              System.debug('count '+count );
          //    System.debug('oppMap.get(acc.ID).size() '+oppMap.get(acc.ID).size());
              if(oppMap.get(acc.ID) != null){
                  if(count == oppMap.get(acc.ID).size() && (MyProflieName == 'Marketing Officer' || MyProflieName == 'Branch Manager') && oppMap.get(acc.ID) != null  ){
                      System.debug('count '+count+' oppMap.get(acc.ID).size() ' +oppMap.get(acc.ID).size());
                      acc.addError('You are not having authority to chage account details.');    
                  }
              }
              
              count = 0;
          }
            
    }
-------------------------------------------------------------------------------------------------------------------------------------------
This method I am calling in Before Update of Account Trigger.

Please suggest me, how I can resolve this error.

Thanks in advance,
Shruti Hasilkar.
Sampath SuranjiSampath Suranji
Hi,

I suggest you to write an SOQL for loop instead standard SOQL query. Try something likem below,
/* remove this line
oppList = [SELECT ID, Name, AccountID, stageName FROM Opportunity WHERE AccountID IN : accountList];
*/

 for (Opportunity opp : [SELECT ID, Name, AccountID, stageName FROM Opportunity WHERE AccountID IN : accountList]) {
		  // add your conditions and rest here
		 if(oppMap.containsKey(opp.AccountID)){
          
         }
 }
regards
 
Jolly_BirdiJolly_Birdi
Hello Shruti,

Please try this below Code:
 
public static void checkC4StageLA(List<Account> accountList, Map<id,Account> oldMap){
        Transient Integer count = 0;
        List<Opportunity> oppList = new List<Opportunity>();
        
        List<Account> accList = new List<Account>();
        Map<ID, List<Opportunity>> oppMap = new Map<ID, List<Opportunity>>();
        
         if(oppList.size() > 0){
            List<Opportunity> tempOppList = new List<Opportunity>();
            for(Opportunity opp: [SELECT ID, Name, AccountID, stageName FROM Opportunity WHERE AccountID IN : accountList]){ //Reason behind to write Query in for loop is: To avoid heap size limit exception.
				tempOppList = new List<Opportunity>();
                if(oppMap.containsKey(opp.AccountID)){
                    tempOppList.addAll(oppMap.get(opp.AccountID));    
                }
                tempOppList.add(opp);
                oppMap.put(opp.AccountID, tempOppList);    
            }
          }
          
          List<Profile> PROFILE = [SELECT Id, Name FROM Profile WHERE Id=:userinfo.getProfileId() LIMIT 1];
          String MyProflieName = PROFILE[0].Name;
          
          for(Account acc: accountList){
              if(oppMap.containsKey(acc.ID) && oppMap.get(acc.ID).size() > 0){
                  for(Opportunity opp: oppMap.get(acc.ID)){
                      if(opp.stageName == 'C4- Payment Disbursed'){
                          count++;    
                      }
                  }
              }    
              if(oppMap.get(acc.ID) != null){
                  if(count == oppMap.get(acc.ID).size() && (MyProflieName == 'Marketing Officer' || MyProflieName == 'Branch Manager') && oppMap.get(acc.ID) != null  ){
                      acc.addError('You are not having authority to chage account details.');    
                  }
              }
               count = 0;
          }
    }



If you find it positive then please like and mark it as best answer.

Thanks,
Jolly Birdi
Abdul KhatriAbdul Khatri
Hi I have tried reducing the code around 10 lines and also less variables and have used SOQL for loop. Please check
 
    public static void checkC4StageLA(List<Account> accountList, Map<id, Account> oldMap){
        Transient Integer count = 0;
        Map<Id, Account> accMap = new Map<Id,Account>(accountList);       
        Map<ID, List<Opportunity>> oppMap = new Map<ID, List<Opportunity>>();
        for(List<Opportunity> oppList : [SELECT ID, Name, AccountID, stageName FROM Opportunity WHERE AccountID IN : accountList]) {
            for(Opportunity opp : oppList) {
                List<Opportunity> tempOppList = new List<Opportunity>();                                        
                if(oppMap.containsKey(opp.AccountID)){
                    tempOppList.addAll(oppMap.get(opp.AccountID));    
                }
                tempOppList.add(opp);
                oppMap.put(opp.AccountID, tempOppList);               
            }
        }
        if(oppMap.isEmpty()) return;
        String MyProflieName = [SELECT Id, Name FROM Profile WHERE Id=:userinfo.getProfileId() LIMIT 1].Name;
        for(Id idAcct : oppMap.keySet()) {      
            for(Opportunity opp : oppMap.get(idAcct)) {
                if(opp.stageName == 'C4- Payment Disbursed'){
                    count++;    
                }
            }
            if(count == oppMap.get(idAcct).size() && (MyProflieName == 'Marketing Officer' || MyProflieName == 'Branch Manager')){
                accMap.get(idAcct).addError('You are not having authority to chage account details.'); 
            }
            count = 0;
        }          
    }