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
Starforce1Starforce1 

Trigger.New pulling Old Values in After Update Opportunity

I'm working with Triggers and I believe there is an unreported bug that I have found regarding Trigger.New and Trigger.Old. Here is the bug:

1. It's a Trigger on Opportunity after update. I even tested this with before update.
2. We are using Salesforce API (wsdl) to update the Opportunity from an external application.
3. When the Trigger fires, the objects Trigger.New and Trigger.Old (any field), holds the same exact values.

I expected that Trigger.New would hold the new values (the ones that will be updated in the database after the order of execution completes), while the Trigger.Old would hold the current/previous values. I made sure there are no workflows and other processes interfering with this particular field. I know I know, there are tons of resources showing how to compare the old and new values and I've tested them all to no avail.

The important thing to note: When a user updates the Opportunity in Salesforce, the Trigger works perfectly fine. The Trigger.New reflects the new values that will be updated, and the Trigger.Old reflects the old values. BUT when we are updating the Opportunity from an external application using the Salesforce API wsdl, the Trigger.Old and Trigger.New objects are exactly identical when the trigger fires. However, after the entire Order of Execution complets, the fields do indeed reflect the new values in the Salesforce interface.

Has anyone had this issue? Or can somebody test/help with any ideas/input?

Thanks a lot.
Chris Gary CloudPerformerChris Gary CloudPerformer
Can you post your trigger code? the reason I ask is because I noticed you are using Trigger.old and Trigger.new Context variables.  Because they are lists, the order of the records in these lists may not be what you expect.  I have had success utilizing Trigger.new and Trigger.oldMap for this type of comparison to make SURE I am comparing the correct records. Below is an example:
trigger TestTrigger on Account (after update){
    for(Account a:Trigger.new){ //looping through the new list
        if(a.AccountNumber == Trigger.oldMap.get(a.Id).AccountNumber){ // finding the old record by Id in the oldMap
            System.debug(LoggingLevel.INFO,'The Account Numbers stayed the same');
        }
    }
}

If you aren't using this method, the reason why your trigger works in SF is because in SF you can only edit one record at a time, so the lists always contain only 1 entry, no room for error there.  However, when updating via the API, you could possibly be sending in more than 1 record, and therefore the list records ordering is not what you expect. If you don't want to post your trigger code, at least in your API, try only updating a single Opportunity record to see if you get the same behavior.
I truly hope this helps. Once you get a resolution, please comment back and mark a comment as 'Best Answer' (even if it isn't mine). This marks this thread as solved and helps the community. Thanks!
Starforce1Starforce1
Chris, thanks for your input. I will test out your idea. Here's the code I'm using to debug it:
 
trigger RatingEmail on Opportunity (after update) {
    String opportunityNumber;
    Opportunity newOpp;
    Opportunity oldOpp;  
 
    if (Trigger.isAfter) {
        // Iterate the Trigger.New Object
        for(Opportunity opp:Trigger.New){
                opportunityNumber = opp.Opportunity_Number__c;     
                newOpp = Trigger.newMap.get(opp.Id);
                oldOpp = Trigger.oldMap.get(opp.Id);
                String DEBUG_OldCR = oldOpp.Rating__c;
                String DEBUG_NewCR = newOpp.Rating__c;
        }  
    }

  }

We narrowed down a lot of this issue, and it turns out that the Opportunity .update through the API Soap WSDL is NOT triggering the Apex Trigger (after or before update). So the main problem here is that the Apex Trigger simply isn't firing after the WSDL does the .update. Even though, in our VB.net code, I can run a SOQL on the Opportunity and see that clearly it updated the field after the .update.
Chris Gary CloudPerformerChris Gary CloudPerformer
A sure fire way to determine if the Trigger is actually firing is to do the following - see updated code snippet below:
trigger RatingEmail on Opportunity (after update) {
    String opportunityNumber;
    Opportunity newOpp;
    Opportunity oldOpp;  
 
    if (Trigger.isAfter) {
        // Iterate the Trigger.New Object
        for(Opportunity opp:Trigger.New){
                opportunityNumber = opp.Opportunity_Number__c;     
                newOpp = Trigger.newMap.get(opp.Id);
                oldOpp = Trigger.oldMap.get(opp.Id);
                String DEBUG_OldCR = oldOpp.Rating__c;
                String DEBUG_NewCR = newOpp.Rating__c;
                System.debug(LoggingLevel.INFO,'\n\n*****\nRating Values - old: ' + DEBUG_OldCR  + ' - new: ' + DEBUG_NewCR + '\n*****\n\n');
        }  
    }

  }
Once you have this in your trigger - turn on the Debug Logging for the User that you are running your API SOAP WSDL Call as.  Run your API Call, and then you should be able to see in your debug Log the Statement printed enclosed in '*****'. This will let you know for sure if your trigger is being fired. I wonder if you are basing the assumption of the trigger not firing based on something else - for example, I noticed your trigger is named 'RatingEmail'.  I hope you aren't basing the fact that you didn't get a 'Rating Email' as an assumption that your trigger is not firing (just throwing that out there - 😜). 
Hope this helps.
 
Starforce1Starforce1
Yup. We've tried this. We see the values in the debug logs, and they are the same from the new object (Trigger.newMap) and the (Trigger.oldMap). I really do believe this is a bug in Salesforce unless triggers are not meant to fire on API SOAP WSDL update call. We're making no assumptions on the firing of the trigger until we see that the old values and new values are different - which thus far it has not been different.
Chris Gary CloudPerformerChris Gary CloudPerformer
Hi!
Did you get this issue resolved?  Sorry again, but I just noticed this - you are using an 'after update' trigger.... Are you getting the same results on 'before update'?
Starforce1Starforce1
This issue is unresolved. I can't see Salesforce fixing it either. We had to find a weird work around, which was to make an update on Opportunity Products, which triggered the update on the Opportunity. Not ideal, but it does allow our process to "work."

The REST API on the other hand works with our exact same process. Thus we are transitioning from SOAP WSDL to REST all together... Which is going to benefit us in the future as well.
DASA YERRISWAMYDASA YERRISWAMY

Hi All,

I am also facing same issue 

I have an application object i am updating some fields in to it then the  after update trigger is firing but in the Trigger.New giving the old values rather than updated value , i dont why its happening 

But the record is updated , isssue in trigger 

Please give me a solution  correct solution for this isssue 

Thanks