+ Start a Discussion
D_RoyD_Roy 

Is it possible to access new value on trigger before insert/update

Hi I 'm required to update a working trigger and ran into what seems to be a basic problem. The trigger as is works after update. I need to check that the value [old] is not what I'm looking for but the value [new] is. Essentially this simulates the 'feild value = X but was not X before'.

 

// loop through trigger records

  for (Integer i=0; i<Trigger.new.size(); i++)

{

//old value must not be specific value 

if(Trigger.old[i].Client_Status__c != 'Exit Trial' && Trigger.old[i].Client_Status__c != 'Churn')

{

//new value must be specific value 

if(Trigger.new[i].Client_Status__c == 'Exit Trial' || Trigger.new[i].Client_Status__c == 'Churn')

   {
... do something here.

This trigger would create a case only but now we want it to update the current account's record type. I found out that you can not update the record that the trigger is currently handling and that the solution wouldbe to have the trigger work before update. Sounds logical but I can't seem to figure out how to test the old and new value before the update.

So long story short, my question is this; can you evaluate the new and old value of a field on trigger records that is launch before update and if so, how?

Best Answer chosen by Admin (Salesforce Developers) 
MiddhaMiddha

Can you please tell what exactly are you trying to do here. From your code, it seems like when client status is updated to churn or exit trial, you are trying to udpate a case.

 

Are you trying to create a new case with that account, if yes, the "update updateCases" should be "insert updateCases". But if you want that change of account status should update some case, you should provide the Case Id from that account which you want to update.

 

In you current code, you are creating a new case object with all the field values but you are not specifying the case id, which is a required field with update DML statement.

 

Hope this helps. 

All Answers

MiddhaMiddha

Yes, you can do that in simillar way as you did it for after update trigger i.e. Trigger.old[i] and Trigger.new[i].

 

/G 

D_RoyD_Roy

Hi GreatG,

 

Are you sure about that?  I modified the trigger to work 'before update' and this is the error I get from the testMethode:

test_newCaseOnAccountCancellation.myUnitTest System.DmlException: Update failed. First exception on row 0 with id 0014000000O4zyjAAB; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, newCaseOnAccountCancellation: execution of BeforeUpdate

caused by: System.SObjectException: DML statment cannot operate on trigger.new or trigger.old

 

This is what made me realize that I might not have access to the new and old values with the 'before' statement and the error that made me try with 'before', which I get from the same trigger but executed 'after update' is:

test_newCaseOnAccountCancellation.myUnitTest System.DmlException: Update failed. First exception on row 0 with id 0014000000O4zxWAAR; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, newCaseOnAccountCancellation: execution of AfterUpdate

caused by: System.Exception: Record is read-only

MiddhaMiddha

Are you trying to use the "update" statement in the before trigger, on the same record that triggered the process? You really need not do that, cause the record itself would be updated by salesforce. 

 

The error shows that you are using some DML statement directly on the Trigger.new/Trigger.old list.

 

DML statment cannot operate on trigger.new or trigger.old

 

I dont think it should be required, in case you have to do that, create a new list and clone the SObject and try updateing that list and not Trigger.new/Trigger.old

 

Can you post some more sections of your code. 

 

/G 

D_RoyD_Roy

Yes, I was trying to create a new Account object from the Trigger.new[i] then update it, I eventually found out what you just mentionned. So instead I tried to insert the new 'RecordTypeId' directly into the Trigger.new[i] object and removed the 'update' statement and now i get the following error.

 

test_newCaseOnAccountCancellation.myUnitTest System.DmlException: Update failed. First exception on row 0 with id 0014000000O5Db7AAF; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, newCaseOnAccountCancellation: execution of BeforeUpdate

caused by: System.DmlException: Update failed. First exception on row 0; first error: MISSING_ARGUMENT, Id not specified in an update call

 

I will keep trying to figure this out on my side but here is the whole tigger code:

trigger newCaseOnAccountCancellation on Account (before update){
   //bulk case update container

   List<Case> updateCases = new List<Case>();
       
    // loop through trigger records
     for (Integer i=0; i<Trigger.new.size(); i++)
    {
        if(Trigger.old[i].Client_Status__c != 'Exit Trial' && Trigger.old[i].Client_Status__c != 'Churn')
        {
            if(Trigger.new[i].Client_Status__c == 'Exit Trial' || Trigger.new[i].Client_Status__c == 'Churn')
            {
                Trigger.new[i].RecordTypeId = '012400000005THpAAM';                       

                Case newCase = new Case(
                    RecordTypeId = '012400000005SDN',
                    AccountId = Trigger.new[i].Id,
                    Subject = 'Account cancellation',
                    Status = 'Open',
                    Priority = 'Medium',
                    Description = 'Message to case owner');
                updateCases.add(newCase);  
            }
        }
    }
    if (updateCases.size() != 0) update updateCases;
}

 

Thanks for helping out!

MiddhaMiddha

Can you please tell what exactly are you trying to do here. From your code, it seems like when client status is updated to churn or exit trial, you are trying to udpate a case.

 

Are you trying to create a new case with that account, if yes, the "update updateCases" should be "insert updateCases". But if you want that change of account status should update some case, you should provide the Case Id from that account which you want to update.

 

In you current code, you are creating a new case object with all the field values but you are not specifying the case id, which is a required field with update DML statement.

 

Hope this helps. 

This was selected as the best answer
D_RoyD_Roy
Oh dear!

You are correct, I want to create a case but being a big fan of the 'cut & paste' to try and get things done faster, I never looked twice that I might have changed some of the old code that used to work... I feel quite silly! Once I canged the update to an insert all went well.

Thanks for all your help GreatG.
Message Edited by D_Roy on 06-19-2009 11:05 AM