function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
pjaenick.ax736pjaenick.ax736 

Insert vs Update Trigger

I have a trigger that needs to fire on before insert, after insert, before update and after update conditions -
 - Each invokes a different class method.
 - The before triggers (insert and update) fire on the affected record(s)
 - The after triggers (insert and update) fire on record(s) of a different object

There is also workflows that perform field updates.  But only want the update triggers to fire for existing records. 

The solutions I've seen (thus far) would work for a "before insert" vs "before update" condition, and similarly work for an "after insert" vs "after update" condition.

How do I prevent the before update and after update triggers from firing on an insert record?
Keep in mind, if the before update trigger (correctly) fires, I DO want the after update trigger to also fire.

Thanks for any strategies / guidance.
Best Answer chosen by pjaenick.ax736
pjaenick.ax736pjaenick.ax736
Discovered an issue with in-line edits and my update triggers... apparently the last-modified-date is NOT updated during an in-line edit, even though it IS updated during stanard EDIT and SAVE.  Changed:
if (mo.createdDate.addSeconds(2) >= mo.lastmodifiedDate) {
to:
if (mo.createdDate.addSeconds(2) >= datetime.now()) {
this solved the in-line edit issue.  Finally, also ran into a code-coverage issue - my "modify" trigger would not fire due to the above hack :)  Final trigger code is as follows:
     } else { // isUpdate
        Map<Id, MyObject__c> trigNewCopyMap = new Map<Id, MyObject__c>(trigger.newMap);
        Map<Id, MyObject__c> trigOldCopyMap = new Map<Id, MyObject__c>(trigger.oldMap);
        for (MyObject__c mo : trigger.new) {
            if(!Test.isrunningtest()) { // ... necessary or on update test coverage won't fire :)
                if (mo.createdDate.addSeconds(2) >= datetime.now()) {
                    trigNewCopyMap.remove(mo.id);
                    trigOldCopyMap.remove(mo.id);
                }
            }
        if (!trigNewCopyMap.isempty()) {
             if (Trigger.isBefore) {
                 MyObjectModel.updateMyObject(trigOldCopyMap, trigNewCopyMap);             } else { // isAfter
                 MyObjectModel.updateMyOtherObject(trigOldCopyMap, trigNewCopyMap);
Hope this helps someone else :)

 

All Answers

Deepak Maheshwari 7Deepak Maheshwari 7

Hi,

If you want workflow rule not to fire while inserting the record. Then put below condition in rule Criteria.

NOT(ISNEW)

Also, In trigger update conditions never fire while inserting the record.

Can you please share your trigger? So that I can analyse and guide you accordingly.

 

Thanks

Deepak

pjaenick.ax736pjaenick.ax736
Thanks Deepak -

This needs to be bulletproof down the line when the SA (or future SA) adds new workflows.

I ~may~ have found a solution (more testing needed).  In the "after" section, I'm going to insert a check to see if the CreatedDate and LastModifiedDate fields are the same - if they are, it's an insert, and the update routine should be ignored (or perhaps I need to allow for a 1 second differential?  Will test this).

As requested, here's my trigger structure:
trigger myTrigger on myObject__c (before insert, after insert, before update, after update) {

    if (Trigger.isInsert) {
        if (Trigger.isBefore) {
            system.debug('>>> Before Insert <<<');
            myObjectModel.insertMyObjects(trigger.new);
        } else { // isAfter
            system.debug('>>> After Insert <<<');
            myObjectModel.insertMyOtherObjects(trigger.new);
        }
    } else { // isUpdate
                if (Trigger.isBefore) {
                    system.debug('>>> Before Update <<<');

                    // testing purposes only:
                    for (myObject__c mo : trigger.new) {
                        system.debug('>>> mo.Id = ' + mo.id + ' <<<);
                        system.debug('>>> mo.createdDate = ' + mo.createdDate + ' <<<');
                        system.debug('>>> mo.lastmodifieddate = ' + mo.lastmodifieddate + ' <<<');
                        system.debug(1/0);  // intentional error during insert testing
                    }

                    myObjectModel.updateMyObjects(trigger.oldMap, trigger.newMap);
                } else { // isAfter
                    system.debug('>>> After Update <<<');
                    myObjectModel.updateMyOtherObjects(trigger.oldMap, trigger.newMap);
                }
            }        
        }
    }
}
Think I might be onto something by checking the createdDate vs lastModifiedDate during the update routine?  Other strategies?

 
pjaenick.ax736pjaenick.ax736
Ok!  So checking the delta between CreatedDate and LastModifiedDate seems to work, (I'm allowing for two seconds):
 
} else { // isUpdate
            Map<Id, Quota__c> trignewcopy = new Map<Id, myObject__c>(trigger.newMap);

            for (myObject__c mo : trigger.new) {
                if (mo.createdDate.addSeconds(2) >= mo.lastmodifiedDate) {
                    trignewcopy.remove(mo.id);
                }
            }
            if (!trignewcopy.isempty()) {
                if (Trigger.isBefore) {
                    ....

Seems a bit of a cludge though - if anyone has a better, "more sanctioned" solution, please reply :)

Thanks,
Pete
 
pjaenick.ax736pjaenick.ax736
Discovered an issue with in-line edits and my update triggers... apparently the last-modified-date is NOT updated during an in-line edit, even though it IS updated during stanard EDIT and SAVE.  Changed:
if (mo.createdDate.addSeconds(2) >= mo.lastmodifiedDate) {
to:
if (mo.createdDate.addSeconds(2) >= datetime.now()) {
this solved the in-line edit issue.  Finally, also ran into a code-coverage issue - my "modify" trigger would not fire due to the above hack :)  Final trigger code is as follows:
     } else { // isUpdate
        Map<Id, MyObject__c> trigNewCopyMap = new Map<Id, MyObject__c>(trigger.newMap);
        Map<Id, MyObject__c> trigOldCopyMap = new Map<Id, MyObject__c>(trigger.oldMap);
        for (MyObject__c mo : trigger.new) {
            if(!Test.isrunningtest()) { // ... necessary or on update test coverage won't fire :)
                if (mo.createdDate.addSeconds(2) >= datetime.now()) {
                    trigNewCopyMap.remove(mo.id);
                    trigOldCopyMap.remove(mo.id);
                }
            }
        if (!trigNewCopyMap.isempty()) {
             if (Trigger.isBefore) {
                 MyObjectModel.updateMyObject(trigOldCopyMap, trigNewCopyMap);             } else { // isAfter
                 MyObjectModel.updateMyOtherObject(trigOldCopyMap, trigNewCopyMap);
Hope this helps someone else :)

 
This was selected as the best answer