0

I want my trigger to update the name of the standard Parent Account field to the name of the custom Parent_Account_for_LAM field whenever it is updated. But I keep receiving this error:

Error:Apex trigger LAM_Account_ParentFieldUpdate caused an unexpected exception, contact your administrator: LAM_Account_ParentFieldUpdate: System.LimitException: Too many DML rows: 10001

This is my trigger so far:

trigger LAM_Account_ParentFieldUpdate on Account (after insert, after update) {         

    List<Account> accs = new List <Account>([SELECT Id, Parent.Name,Parent_Account_for_LAM__c FROM Account]);

    if(Trigger.isUpdate){
    for (Account a : Trigger.new){

            if(a.Parent.Name != a.Parent_Account_for_LAM__r.Name){
                Account accounttoUpdate = new Account (Id = a.Id);
                accounttoUpdate.Parent.Name = a.Parent_Account_for_LAM__r.Name;
                accs.add(accounttoUpdate);
            }

        update accs;
         }
    }

}
3
  • when you update the account, you are calling the trigger again. It is a recursive issue.
    – m Peixoto
    Commented Mar 13, 2019 at 14:54
  • I already told you how to fix this on another question you asked: salesforce.stackexchange.com/questions/253366/… Granted my answer doesn't point out this specific issue, but if you use the code I provided you wouldn't have had this issue to begin with.
    – gNerb
    Commented Mar 13, 2019 at 14:59
  • @gNerb the solution does not fix my problem for this particular question. Per your instructions I created a new question with the same contact issue: salesforce.stackexchange.com/questions/254438/…
    – user64312
    Commented Mar 19, 2019 at 14:23

3 Answers 3

3

You're inadvertently trying to update every Account in your database, in addition to some other logical issues.

You do this:

List<Account> accs = new List <Account>([SELECT Id, Parent.Name,Parent_Account_for_LAM__c FROM Account]);

and then you also do this:

update accs;

in a for loop, no less. Since you're querying with no filters, you've just tried to update every Account in Salesforce, as many times over as there are Accounts in the trigger set. That will wipe out your allowed DML rows very quickly, and it's certainly not what you are intending to do.

What you seem to be aiming to do is query those Accounts that are in scope for your trigger so that you can access parent values. To do so, you'd need a filter on your query:

List<Account> accs = new List <Account>([
    SELECT Id, Parent.Name,Parent_Account_for_LAM__c 
    FROM Account
    WHERE Id IN :Trigger.newMap.keySet()
]);

Then, you would iterate over accs (not Trigger.new).

You'll probably also want to handle the case where multiple child Accounts of the same parent Account are being updated; the usual pattern is to accumulate updates not in a List<Account> but a Map<Id, Account>, and at the very end of your trigger do update myMap.values(); Failing to do so will land you an exception for duplicate values in the update list.

Your update code is also incorrect.

            Account accounttoUpdate = new Account (Id = a.Id);
            accounttoUpdate.Parent.Name = a.Parent_Account_for_LAM__r.Name;
            accs.add(accounttoUpdate);

You cannot update related records in SOQL this way. Your accounttoUpdate Id should be the Id of the parent, and you should populate the fields you want to update directly on that record. You also need to check whether the parent is present - i.e., is not null - before you try to construct the updatable record.

Your trigger will recurse up the Account hierarchy, but I suspect that may be what you want here. The recursion should be naturally limited due to the maximum depth of the Account hierarchy, and should be further limited by "do I need to do work" checks like the Name comparison you perform. You may also wish to check whether or not parent lookups themselves have changed prior to performing the query at all, but that's really a next-version upgrade once you get this working at all.

1
  • Thanks for the help I'm relatively new to developing so clearly I need to look at more trailheads and docs but thanks for pointing me in the right direction
    – user64312
    Commented Mar 13, 2019 at 15:54
0

Your query is too broad. You should include a WHERE clause to specify which records are returned to avoid pulling the data from every existing Account record. In this case it looks like you are only performing action on the updated records, so use their IDs as a guide.

Before your query, iterate over trigger.new and add the ids to a set. Use this set to SELECT those records in your query.

-1

It seems your trigger goes on recursive. You need to stop recursive by using the Static variable. As below

Static Class

public class MyClass
{ 
    public static boolean firstRun = true; 
} 

By using the static variable you can stop the recursive.

3
  • 1
    The recursion is not the problem with this trigger, and static Booleans of this type are not a good fix for trigger recursion issues.
    – David Reed
    Commented Mar 13, 2019 at 15:01
  • @David, I undersatnd the logic which has written is also wrong, but we can't give suggestion for the logic. As they know better then us. I was just givin the solution as it becomes recusruve.
    – Piyush
    Commented Mar 13, 2019 at 15:03
  • 1
    I will respectfully disagree there. The crux of this question is the broken logic, and we absolutely can comment upon it. The recursion is not the problem, or at least not the proximate issue, here. Further, using a firstRun or runOnce Boolean is the wrong solution to trigger recursion. That solution fails on allOrNone=false, on multiple DMLs in a transaction, on > 200 records in a transaction, etc.
    – David Reed
    Commented Mar 13, 2019 at 15:09

You must log in to answer this question.