[SalesForce] System.LimitException: Too many SOQL queries: 101 when deployng

I have faced with the annoing error: System.LimitException: Too many SOQL queries: 101. I checked all that may hits the governor errors but still no luck….
Can you point me where in the code hits the limits?
The error occures only when deployng in to production:

Class Name: TestITAssetProcessingBatchClass
MethodName: testBatch
Error Msg: System.LimitException: Too many SOQL queries: 101
Stack Trace: Trigger.CashFlowIntegration: line 10, column 1

This is TestITAssetProcessingBatchClass:

@isTest(SeeAllData=false)
class TestITAssetProcessingBatchClass {

static testmethod void testBatch() {

Test.startTest();
   Account acc = new Account();
   acc.Name = 'Test Account';
   insert acc; 

List<IT_Asset__c> st=new List<IT_Asset__c>(); 
    for(integer i = 0;  i < 25; i++){
        IT_Asset__c it = new IT_Asset__c();
            it.Account__c = acc.Id; 
            it.FrstDayOfMnth__c = true; 
            it.Quantity__c = 4;
        st.add(it);
    }
    insert st;

    Database.BatchableContext bc;
    ITAssetProcessingBatch obj=new ITAssetProcessingBatch();
    obj.query = 'Select id From IT_Asset__c Where Quantity__c = 4 Limit 100';
    obj.start(BC);
    obj.execute(BC, st);
    obj.finish(BC);

    System.assertEquals(25, Database.query(obj.query).size() );
Test.stopTest();
}
}

And This is my trigger CashFlowIntegration:

trigger CashFlowIntegration on Cash_Flow__c (before insert, before update ) {

Set<String> AccNum = new Set<String>(); 
for (Cash_Flow__c CF : trigger.new) { 
    AccNum.add(CF.AccNumber__c); } 

Map<String, Account_Number__c> AccountNumbers = new Map<String, Account_Number__c>();

List <Account_Number__c> rec = [ SELECT Account_No__c, Account__c FROM Account_Number__c WHERE Account_No__c IN :AccNum LIMIT 1];     
List <Account_Number__c> rec2 = [ SELECT Account_Number_Old__c, Account__c FROM Account_Number__c WHERE Account_Number_Old__c IN :AccNum LIMIT 1];
List <Account_Number__c> rec3 = [ SELECT Acronym__c, Account__c FROM Account_NUmber__c WHERE Acronym__c IN :AccNum LIMIT 1];
if (rec != NULL){
    for (Account_Number__c record : rec){ 
         AccountNumbers.put(record.Account_No__c, record);
        }
}
if (rec2 != NULL){
      for (Account_Number__c record2 : rec2){       
          AccountNumbers.put(record2.Account_Number_Old__c, record2);
        }  
}
if (rec3 != NULL){
    for (Account_Number__c record3 : rec3) {
        AccountNumbers.put(record3.Acronym__c, record3);
    }
}

    for (Cash_Flow__c CF : Trigger.new){
        Account_Number__c siteAccount = AccountNumbers.get(CF.AccNumber__c);
        Id parentId = (siteAccount == null) ? null : siteAccount.Id;
        Id accId = (siteAccount == null) ? null :siteAccount.Account__c;
        CF.Amount__c = -1*CF.Amount__c;
        CF.Account_Number__c = parentId;
        CF.Account__c = accId;
        if (accId == NULL){
            CF.Account__c = '001b000000r63RN';//'0017E000009c6QB';
        }
    }
 }

Best Answer

The problem is that the ITAssetCashFlowCreate trigger and CashFlowIntegration are not bulk safe. The ITAsset trigger upserts CashFlow records inside the for loop. So when you update the list of 25 ITAssets (presumably occurs in the batch), you call the upsert operation 25 times. The first time on one record, the second time on two, etc. Thus the loop in the CashFlowIntegration trigger will run 325 times. You have three SOQL triggers inside that loop. Thus an operation updating the 25 ITAssets will cause 975 SOQL queries to run.

Related Topic