+ Start a Discussion
sh-at-youseesh-at-yousee 

Close to govenor limits

Hi all,

 

I have a trigger where the SOQL and DML statements fired are getting close to the govenor limits.

 

One of the issues is this:

    for(Opportunity o : Trigger.New) {
    	// This only concerns Opportunities being inserted
    	if(Trigger.isInsert) {
	    	// If it is the first Opportunity ensure that
	    	// Type is set to New Business.
    		account = [SELECT Id, Number_of_Opportunities__c FROM Account WHERE Id = :o.AccountId];
    		if(account.Number_of_Opportunities__c == 0) {
    			o.Type = 'New Business';
    		}
    	}
    }

 
Now, we all know it's a big no-no to have a select within a loop as the code above. My initial thought was I'd simply use this instead:

 

 

 

    for(Opportunity o : Trigger.New) {
    	// This only concerns Opportunities being inserted
    	if(Trigger.isInsert) {
	    	// If it is the first Opportunity ensure that
	    	// Type is set to New Business.
    		if(o.Account.Number_of_Opportunities__c == 0) {
    			o.Type = 'New Business';
    		}
    	}
    }

 
As you can see the select statement is now gone but this leaves me with another problem. It seems if I do that (access Number_of_Opportunities__c through o.Account it is null. Actually, it seems all fields found like that return null.

 

Any idea why?

 

Thanks.

 

/Søren Nødskov Hansen

 

Best Answer chosen by Admin (Salesforce Developers) 
jeremyyjeremyy

Objects you access through Trigger.new and Trigger.old aren't fully fleshed out object graphs. You need to loop through the Opportunities, build a List of Account Ids, then do one query for accounts that is something like "... FROM Account WHERE Id IN :accountIds"

All Answers

jeremyyjeremyy

Objects you access through Trigger.new and Trigger.old aren't fully fleshed out object graphs. You need to loop through the Opportunities, build a List of Account Ids, then do one query for accounts that is something like "... FROM Account WHERE Id IN :accountIds"

This was selected as the best answer
sh-at-youseesh-at-yousee

Hi,

 

Thanks, I did not know that objects accessed through Trigger.new and Trigger.old weren't fully populated.

 

/Søren Nødskov Hansen

sfdcfoxsfdcfox

To clarify on the statement, the entire object in Trigger.new and Trigger.old has all of its fields populated, but not its relationships. So for an opportunity trigger, Opportunity.AccountId is available, since it is a field, but Opportunity.Account.Name is not, since it is a relationship. Similarly, Opportunity.CustomObjectLookup__c would be populated, but Opportunity.CustomObjectLookup__r.Name would not be.