[SalesForce] Too many SOQL queries

This question has been asked before, but none of the answers on those threads have helped so far.

Getting the following error when trying to deploy a test class from the sandbox to production in the Force.com IDE:

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, LeadPerson: execution of AfterInsert caused by: System.Exception: Too many SOQL queries: 101

LeadPerson trigger looks OK, e.g., no SOQL calls inside a loop.

trigger LeadPerson on Lead (after insert) {
    Map<Id, Lead> leadMap = new Map<Id, Lead>();
    Map<String, Lead> leadEmailMap = new Map<String, Lead>();

    for(Lead lead : Trigger.new) {
        if (lead.Email != null) {
            leadMap.put(lead.Id, lead);
            leadEmailMap.put(lead.Email, lead);
        }
    }

    Map<String, Person__c> personMap = new Map<String, Person__c>();
    for (Person__c p : [SELECT Id, Email__c FROM Person__c WHERE Email__c IN :leadEmailMap.keySet()]) {
        personMap.put(p.Email__c, p);
    }

    List<Person__c> addPersons = new List<Person__c>();
    List<PersonHistory__c> addPersonHistorys = new List<PersonHistory__c>();
    List<Lead> addPersonLead = new List<Lead>();
    Map<String, String> addPersonEmails = new Map<String, String>();

    for(Lead lead : Trigger.new) {
        if (lead.Email != null) {
            if (personMap.containsKey(lead.Email)) {
                // Create PersonHistory__c record for existing Person__c records
                Person__c getPerson = personMap.get(lead.Email);
                PersonHistory__c newPersonHistory = new PersonHistory__c();
                newPersonHistory.Person__c = getPerson.Id;
                newPersonHistory.RecType__c = 'LEAD';
                newPersonHistory.RecSubType__c = lead.inq_type__c;
                newPersonHistory.SFID__c = lead.Id;
                newPersonHistory.RecTypeStatus__c = 'NEW';
                addPersonHistorys.add(newPersonHistory);
            } else {
                // Create Person__c and PersonHistory__c record for NEW Person__c records
                String firstInitial = '';
                if (lead.FirstName != null) {
                    firstInitial = lead.FirstName.substring(0, 1);
                }

                if (!addPersonEmails.containsKey(lead.Email)) {
                    addPersonEmails.put(lead.Email, 'EMAIL');
                    Person__c newPerson = new Person__c();
                    newPerson.Email__c = lead.Email;
                    newPerson.AltKey__c = firstInitial + lead.LastName + lead.PostalCode;
                    newPerson.Current_Status__c = 'NEW';
                    addPersons.add(newPerson);
                    addPersonLead.add(lead);
                }
            }
        }
    }

    // INSERT NEW Person__c records
    List<Database.SaveResult> newPersonResult = Database.Insert(addPersons);
    for (integer i = 0; i < newPersonResult.size(); i++) {
        // Create PersonHistory__c records for new Person__c records
        PersonHistory__c newPersonHistory = new PersonHistory__c();
        newPersonHistory.Person__c = newPersonResult.get(i).getId();
        newPersonHistory.RecType__c = 'LEAD';
        newPersonHistory.RecSubType__c = addPersonLead.get(i).inq_type__c;
        newPersonHistory.SFID__c = addPersonLead.get(i).Id;
        newPersonHistory.RecTypeStatus__c = 'NEW';
        addPersonHistorys.add(newPersonHistory);
    }
    insert addPersonHistorys;
}

The debug log doesn't show a transaction having more than 5 out of 100 SOQL queries in the CUMULATIVE_LIMIT_USAGE sections. Not sure where to look next. Any help is appreciated.

Best Answer

One thing to remember with deploying to production. ALL of the testclasses have to be executed as part of the deployment. Your code looks pretty good from a SOQL standpoint, does need the DML moved outside the loop as was mentioned before), so it is probably a case where other test executions are putting you close to the limit, and your 1 soql is putting the entire transaction over the limit. Do a "Run All Tests" in production, and look at the resulting Debug log. At the very end, you should see a summary count of the SOQLs that were executed. You can then scan through the log for the SOQL summaries listed with each test that is executed, and use this to narrow down the offending code or test method.

Related Topic