Skip to main content
Hi both the below triggers wotks fine , I have a question here , in my first trigger posted below I am using DML update accs.values();,If I remove DML trigger doesn't work, in my second trigger If I use DML update contactListToUpdate;, iam getting error

 "Error: Apex trigger ownerChange caused an unexpected exception, contact your administrator: ownerChange: execution of BeforeUpdate

caused by: System.DmlException: Update failed. First exception on row 0 with id 0039000001yu7JUAAY; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, changeOwner: execution of AfterUpdate

caused by: System.DmlException: Update failed. First exception on row 0 with id 0019000001i0umdAAA; first error: SELF_REFERENCE_FROM_TRIGGER, Object (id = 0019000001i0umd) is currently in trigger ownerChange, therefore it cannot recursively update itself: []

(): []: ()"

Now Iam confused whether we can use DML operations in before triggers or not.Can some explain me if we can use DML operations in before triggers

trigger ownerChange on Account (before insert, before update) {

List<id> accountIdsList = new list<id>();

list<contact> contactListToUpdate = new list<contact>();

for(account acc : trigger.new){

accountIdsList.add(acc.id);

}

list<contact> contactList = [select id from contact where accountId IN:accountIdsList ];

for(account acc : trigger.new){

if(acc.ownerId!=trigger.oldMap.get(acc.id).ownerId){

for(contact con : contactList){

con.ownerId = acc.ownerId;

contactListToUpdate.add(con);

}

}

update contactListToUpdate;

}

}

?

/ The trigger needs to check all the other Opportunities related to the Account of the Opportunity being updated. It should check to see if any of the Opportunities have a StageName equal to 'Closed Won ',

// if so, it should update the account Type to 'Customer'. If none of the Opportunities are closed won, the Account Type should be 'Prospect

trigger updateAccountIfOppCustomer on Opportunity (before insert, before update) {

list<opportunity> accOpps = new list<opportunity>();

list<id> accountIds = new list<id>();

for(opportunity opp:trigger.new){

accountIds.add(opp.accountId);

}

list<opportunity> opps = [select id,AccountId,StageName from opportunity where accountId IN:accountIds];

map<id,account> accs = new map<id,account>([select id,type from account where id IN:accountIds]);

system.debug('accs '+accs );

for(opportunity o:opps){

if (o.StageName == 'Closed Won' || o.StageName == 'Customer Reseller') {

//acc.type = 'prospect';

accs.get(o.accountId).type='prospect';

}

}

update accs.values();

}

 
6 réponses
  1. 15 déc. 2023, 19:37

    The question was long time ago, but if you are here cause you are beginer in Apex this is the answer: Remove the DML statement.

     

    Why?

    The system saves the records that fired the before trigger after the trigger finishes execution. You can modify the records in the trigger without explicitly calling a DML insert or update operation. If you perform DML statements on those records, you get an error.

     

    You can find this information in Trailhead's Apex Triggers module.

    https://trailhead.salesforce.com/content/learn/modules/apex_triggers

     

    If it helped you, please mark it as the best answer.

0/9000