You need to sign in to do that
Don't have an account?
Update After Trigger: Update same object
Hi, I am new to APEX development. I have created a new trigger to update a custom field on the Lead object. I have to use 'after update' since I need to have the OwnerId. It works, however, I just KNOW it is not properly coded. Can someone please review and let me know how it really should be? Especially regarding what is referred to as ‘bulkification’?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | trigger UpdateLeadOwner2AfterInsertUpdate on Lead (after insert, after update) {
string txtLdID;
|
2. Since you are updating the same object, this will result in recursive trigger. So you can have a boolean field(default value true), which you set to false while you update the record. If the value of this field is false, dont fire the trigger.
3. Other option would be to have a class and a static boolean variable in that class. Set this field to false before you issue the update statement and add an if statement before the 1st line of your trigger. IF(BOOLEANVARIABLE){your trigger code}
4. If your trigger is only for updating owners, you can add a condition in the for loop:
if(l.ownerId != Trigger.OldMap().get(l.Id).ownerId)
{then proceed}
All Answers
Generally speaking, if you want to update the object that is in the trigger, you'd want to do that in a before trigger, not an after trigger.
Yes, that would be ideal. But since I am dealing with Leads and we have Lead Assignment Rules, I need the record after all updates and it has been committed to the database so I have the current OwernId.
in that case, since you have to... :)
in your after trigger, you can create a new object and set its ID to the Id of the trigger object. All the same 'bulkifying' rules apply.
for (Lead l : trigger.new) {
Lead ld = new Lead(Id = l.id);
}
I don't need to create a new object, I just need to update the leads that were changed. Is my code correct for the trigger I created? As I stated, the current trigger works, but I want to be creating and writing efficient code.
Thanks for your help!
in an after trigger, the object in the trigger is read-only, you will not be able to just update the fields as you would in a before trigger.
2. Since you are updating the same object, this will result in recursive trigger. So you can have a boolean field(default value true), which you set to false while you update the record. If the value of this field is false, dont fire the trigger.
3. Other option would be to have a class and a static boolean variable in that class. Set this field to false before you issue the update statement and add an if statement before the 1st line of your trigger. IF(BOOLEANVARIABLE){your trigger code}
4. If your trigger is only for updating owners, you can add a condition in the for loop:
if(l.ownerId != Trigger.OldMap().get(l.Id).ownerId)
{then proceed}
Shailesh,
I actually did end up changing the code to the following. I might have made it more complex than necessary since I am dealing with the same object, but it works. Adding the code for the recursive issue is a good call. I will look into that, as well. Thanks!!
trigger UpdateLeadOwner2AfterInsertUpdate on Lead (after insert, after update) {
string txtLdID;
Set<Id> leadIds = new Set<Id>();
//create a list of the records that need updating
for (Lead oLead : trigger.new) {
txtLdID = oLead.OwnerId;
if (oLead.Lead_Owner_2__c <> oLead.OwnerId && txtLdID.startsWith('00G') == FALSE) {
leadIds.add(oLead.Id);
}
}
//Iterate through all records that need updating
If (leadIds.isEmpty() == false) {
List<Lead> listLeads = [SELECT id, OwnerId, Lead_Owner_2__c from Lead WHERE Id in :leadIds];
For (Lead oLead : listLeads) {
oLead.Lead_Owner_2__c = oLead.OwnerId;
}
//Post the changes to the database
If (listLeads.isEmpty() == false) {
Update listLeads;
}
}
}
your earlier code was perfect except few changes which I suggested. The code that you posted now also does the same job, but the second for loop is not needed. You can do the same thing in your 1st for loop.