+ Start a Discussion
naveen1685naveen1685 

too many soql queries 101

Facing the issue "Too many SOQL queries: 101" at the highlighted line in the following code :

 

public with sharing class AccountTriggerHandler {
     
    private boolean m_isExecuting = false;
    private integer BatchSize = 0;
    public static boolean isDeletedByTrigger = false;
    public set<Id> recordTypeSet = new set<Id>();
    public AccountTriggerHandler(boolean isExecuting, integer size){
        m_isExecuting = isExecuting;
        BatchSize = size;
        for(RecordType rt : [Select Id, DeveloperName From RecordType Where DeveloperName Like '%Ukraine%' And SobjectType='Account']){
            recordTypeSet.add(rt.Id);
        }
    }
    
    public void OnAfterInsert(List<Account> newObjects){
         createNewContacts(newObjects);
    }

    private void createNewContacts(list<Account> accountList){
        /*set<Id> recordTypeSet = new set<Id>();
        for(RecordType rt : [Select Id, DeveloperName From RecordType Where DeveloperName Like '%Ukraine%' And SobjectType='Account']){
            recordTypeSet.add(rt.Id);
        }*/
        list<Contact> contactsToBeInserted = new list<Contact>();
        for (Account acc : accountList){
            if(recordTypeSet.contains(acc.RecordTypeId))
              contactsToBeInserted.add(new Contact (AccountId=acc.Id, LastName= acc.Name, Position__c = 'Virtual',Country__c=acc.Base__Country__c,City__c = acc.City__c));
        }
        if(contactsToBeInserted.size()>0)
           insert contactsToBeInserted;
    }
    
    public void OnAfterUpdate(map<Id, Account> newObjects, map<Id, Account> oldObjects){        
         updateContacts(newObjects, oldObjects);
    }
    
    private void updateContacts(map<Id, Account> accountNew, map<Id, Account> accountOld){
        
        /*List<RecordType> rectype = new list<RecordType>();
        set<Id> recordTypeSet = new set<Id>();
        rectype = [Select Id, DeveloperName From RecordType Where DeveloperName Like '%Ukraine%' And SobjectType='Account'];
        for(RecordType rt : rectype ){
            recordTypeSet.add(rt.Id);
        }*/
        
        set<Id> accountsWithNameChanges = new set<Id>();
        for (Id key : accountNew.keySet()){
            if(recordTypeSet.contains(accountNew.get(key).RecordTypeId)){
               if(accountOld.get(key).Name <> accountNew.get(key).Name){
                  accountsWithNameChanges.add(key);
               }
            }
        }
        
        list<Contact> contactsToBeUpdated = new list<Contact>();
        for(Contact con : [Select id, LastName,AccountId
                           From Contact 
                           Where AccountId IN :accountsWithNameChanges 
                            And Position__c = 'Virtual']){
            con.LastName = accountNew.get(con.AccountId).Name;
            contactsToBeUpdated.add(con);
        }
        if(contactsToBeUpdated.size() > 0)
            update contactsToBeUpdated;
    }
    
    public void OnBeforeDelete(map<Id, Account> oldObjects){
        deleteVirtualContacts(oldObjects);
    }
    
    private void deleteVirtualContacts(map<Id, Account> accountOld){
        isDeletedByTrigger = true;
        list<Contact> contactsToBeDeleted = [Select Id From Contact Where AccountId IN :accountOld.keySet() and Position__c = 'Virtual'];
        if(contactsToBeDeleted.size()>0)
            delete contactsToBeDeleted;         
    }
}

 

Please advice how to solve this issue.

 

Best Answer chosen by Admin (Salesforce Developers) 
naveen1685naveen1685

The issue is solved. We put the recordtype query in a static block which is called only once now.

 

Here is the modified code:

 

 public static set<Id> recordTypeSet = new set<Id>();
    
     static{   
        for(RecordType rt : [Select Id, DeveloperName From RecordType Where DeveloperName Like '%Ukraine%' And SobjectType='Account']){
            recordTypeSet.add(rt.Id);      
          }
        }

All Answers

souvik9086souvik9086

Hi,

 

for(RecordType rt : [Select Id, DeveloperName From RecordType Where DeveloperName Like '%Ukraine%' And SobjectType='Account'])

More than 100 rows are fetched through this. Thats why the error came. You can use batch apex to query some perticular data at time.

OR

You can use limit of 100

 

If this post is helpful please throw Kudos.If this post solves your problem kindly mark it as solution.

Thanks

 

AsitM9AsitM9

You have called this class more than hundred times.

 

to avoid this use

 

Account acc= new Account();
acc.RecordTypeId=Schema.SObjectType.acc.getRecordTypeInfosByName().get('YUOR RTNAme').getRecordTypeId();

 

naveen1685naveen1685

How to avoid the following query by the method suggested by you:

 

Select Id, DeveloperName From RecordType Where DeveloperName Like '%Ukraine%' And SobjectType='Account'

 

The problem here is that we do not want recordtypeid with a specific name. We need to fetch all recordtypeids having "Ukraine".

Salesforce SolutionsSalesforce Solutions
Have you checked your debug logs to see exactly what queries are executing? The error message indicates that there are too many queries, not too many results from this one query, so this query, or some other query or queries must be getting called a total of over 100 times.
Avidev9Avidev9
+1 for salesforce solutions this error is related to Number of queries being executed and not due to number of results beign returned.

Seems like your account contact trigger are going recursive.

Account >>> Contact >>>Acoount>>Contact....... this goes on . Check the logs that will give more clear insight on it
naveen1685naveen1685

Modified the code to get record types to avoid SOQL queries:

 

public set<Id> recordTypeSet = new set<Id>();
    public AccountTriggerHandler(boolean isExecuting, integer size){
        m_isExecuting = isExecuting;
        BatchSize = size;
        recordTypeSet.add(Schema.SObjectType.Account.getRecordTypeInfosByName().get('Ukraine Agroholding').getRecordTypeId());
        recordTypeSet.add(Schema.SObjectType.Account.getRecordTypeInfosByName().get('Ukraine Competitor').getRecordTypeId());
        recordTypeSet.add(Schema.SObjectType.Account.getRecordTypeInfosByName().get('Ukraine DC Sales plan').getRecordTypeId());
        recordTypeSet.add(Schema.SObjectType.Account.getRecordTypeInfosByName().get('Ukraine Distributor').getRecordTypeId());
        recordTypeSet.add(Schema.SObjectType.Account.getRecordTypeInfosByName().get('Ukraine Grower').getRecordTypeId());
        recordTypeSet.add(Schema.SObjectType.Account.getRecordTypeInfosByName().get('Ukraine Other Account').getRecordTypeId());
        recordTypeSet.add(Schema.SObjectType.Account.getRecordTypeInfosByName().get('Ukraine Seeds Producer').getRecordTypeId());
        recordTypeSet.add(Schema.SObjectType.Account.getRecordTypeInfosByName().get('Ukraine Vegetable Grower').getRecordTypeId());

 

 

Now facing the error Too many record type describes: 101.

 

Please advise

naveen1685naveen1685

The issue is solved. We put the recordtype query in a static block which is called only once now.

 

Here is the modified code:

 

 public static set<Id> recordTypeSet = new set<Id>();
    
     static{   
        for(RecordType rt : [Select Id, DeveloperName From RecordType Where DeveloperName Like '%Ukraine%' And SobjectType='Account']){
            recordTypeSet.add(rt.Id);      
          }
        }

This was selected as the best answer