0

So I have a trigger that I want to run everytime a record is updated and created. However, when I use after insert and before update I get a record is locked error when creating the record.

How can I run this trigger on both record edit and creation?

Better yet, is it possible to update any field "after update" or "after insert"?

trigger CalcBenefit on EA_App__c (before update, after insert) {
//works for update only.  insert throws error because I'm trying to change value
for (EA_App__C ea : Trigger.new){

    EA_App__C oldEA = Trigger.oldMap.get(ea.Id);

    if (ea.X3_Month_Income__c > CalculateBenefit.getMax(integer.valueOf(ea.Family_Size__c))){
        ea.App_Status__c = 'DENIED';            
        ea.Benefit_Amount__c = 0;                 

    }else if (ea.X3_Month_Income__c <= CalculateBenefit.getMin(integer.valueOf(ea.Family_Size__c)) && ea.App_Status__c != 'PAID'){
        //how to compare to old? 
        //&& (ea.X3_Month_Income__c != oldEA.X3_Month_Income__c || ea.Family_Size__c != oldEA.Family_Size__c)
        ea.Benefit_Amount__c = 0;                 
        ea.App_Status__c = 'SENT FOR APPROVAL';                

    }else{
        ea.App_Status__c = 'PAID';
        ea.Benefit_Amount__c = CalculateBenefit.calc(ea.X3_Month_Income__c, integer.valueOf(ea.Family_Size__c), ea.Fuel_Cost__c, '2015');
    }

}

}

1
  • I should have been using BEFORE INSERT and if I use before insert then I needed to put an IF (trigger.ISUPDATE) before using the OLDMAP.GET method.
    – tjcinnamon
    Nov 13, 2015 at 19:54

2 Answers 2

1

You can use before insert to modify records before they're saved to the database, which should work well enough for your purposes.

You can simply set oldEA to a blank record, which will also satisfy your "changed fields" conditions:

EA_App__C oldEA = Trigger.isInsert? new EA_App__c(): Trigger.oldMap.get(ea.Id);

If it doesn't work, you can also choose to update the records recursively:

if(Trigger.isAfter && Trigger.isInsert) {
    update Trigger.new.deepClone(true);
} else {
    // Before Update Logic
}
3
  • I think the problem is the methods for the class I'm calling reference saved values in the database. I may have to rework those and pass the object instead of the object ID (because the ID won't be created yet). Is that possible, to pass the unsaved object?
    – tjcinnamon
    Nov 12, 2015 at 21:36
  • @tjcinnamon Without knowing how your fields are laid out, I can't tell if you could just do before insert, which is why I also suggested cloning Trigger.new and updating it recursively.
    – sfdcfox
    Nov 12, 2015 at 21:38
  • I will try before insert instead. It seems like the proper way to go about doing it. The ability to clear the old record seems like a neat way to go about things.
    – tjcinnamon
    Nov 12, 2015 at 21:40
1

Is there a reason that your trigger needs to be after insert rather than before insert? Usually, after insert is used to update other records in the database after this record has been inserted. You frequently need to wait so that you are sure that the record has its final data (all other before insert triggers have run). Salesforce stops you from changing values directly on the record because the record has already been committed to the database. Your value changes in the after trigger will not impact the record.

Some valid cases for needing an after trigger would be that you have cross-object formulas that you need to be calculated or you need the Id to get data from related records. If neither of these are the case I would suggest moving your trigger to operate before insert. If you must use after insert you will need to construct a new instance of your SObject and do another update DML statement.

2
  • I think you're right. Before insert will work better. I have methods that check values in the database. I may need to pass the unsaved object to those methods instead of the object ID (when the methods use that as a lookup). Is that possible to do?
    – tjcinnamon
    Nov 12, 2015 at 21:38
  • Yes, simply pass the SObject to the method. If you want to get fancy, you can overload your methods so they take either an Id (and query for the SObject) or just an SObject (no query required: lower limits usage!).
    – dsharrison
    Nov 12, 2015 at 21:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .