+ Start a Discussion
Sylvio AvillaSylvio Avilla 

AfterUpdate Trigger Error in Production

Hello Everyone,

I'm facing a problem and would like some help to correct it
The following code works perfect on my developer account:

trigger ReagendarServico on Controle_de_Manuten_o__c (after update) {
   List<Controle_de_Manuten_o__c> co = [select Id,Veiculo__c,N_mero_de_Reagendamentos__c,Reagendamento_do_Servi_o__c,Status_do_Servi_o__c,Data_e_Hora_da_Solicita_o_do_Servi_o__c,Posicao__c,Solicitado_Por__c,Observa_o__c,Defeito__c,Componente__c from Controle_de_Manuten_o__c 
                                        where Id=:trigger.new];
    for (Controle_de_Manuten_o__c cont: co){
        if(cont.Status_do_Servi_o__c== 'Não Executado')
        Controle_de_Manuten_o__c novoservico = new Controle_de_Manuten_o__c(
        Reagendamento_do_Servi_o__c =cont.ID,
        N_mero_de_Reagendamentos__c =cont.N_mero_de_Reagendamentos__c + 1,
        Data_e_Hora_da_Solicita_o_do_Servi_o__c = cont.Data_e_Hora_da_Solicita_o_do_Servi_o__c,
        Posicao__c = cont.Posicao__c ,
        Veiculo__c = cont.Veiculo__c,
        Solicitado_Por__c = cont.Solicitado_Por__c,
        Observa_o__c = cont.Observa_o__c,
        Defeito__c = cont.Defeito__c,
        Componente__c= cont.Componente__c,
        Status_do_Servi_o__c = 'Reagendar'
        insert novoservico;
        cont.Status_do_Servi_o__c = 'Reagendado';
        update cont;
        update novoservico;        
But when I use it on Production (my company’s environment) the following error is generated:

Update failed. First exception on row 0 with id a0ai000000BfT0qAAF; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, SGAAF.ReagendarServico: execution of AfterUpdate caused by: System.NullPointerException: Attempt to de-reference a null object (SGAAF): []
Error is in expression '{!SAVE}' in component <apex:commandButton> in page sgaaf:atualizaservicos: (SGAAF)

Most probably cont variable is still null at this point.
Since your are going to update the object with new value you need to instantiate the object. Good practice is to take the values in a List and then do a null check before doing a update. 

for eg: 

 if (newAccount != null)
Do something

Well - you would never want to do an update to cont inside of your loop.  DML's (Insert, Update, Delete) should never be done in a loop. 

And this trigger is an AFTER UPDATE on the Controle_de_Manuten_o__c object - but yet - you re-aquire the record and do another update on it.  so, when you do the update - it would re-fire your trigger - probably not what you wanted.   So, the trigger should probably be a BEFORE UPDATE trigger. 

I might be wrong - but I'm guessing you'll want something like this...
trigger ReagendarServico on Controle_de_Manuten_o__c (before update) {

  list<Controle_de_Manuten_o__c> novoServicos = new list<Controle_de_Manuiten_o__c>();

  for(Controle_de_Manuten_o__c cont :trigger.new) {
    if(cont.Status_do_Servi_o__c == 'Nao Executado') {
      novoServicos.add(new Controle_de_Manuten_o__c(
        Reagendamento_do_Servi_o__c =cont.ID,
        N_mero_de_Reagendamentos__c =cont.N_mero_de_Reagendamentos__c + 1,
        Data_e_Hora_da_Solicita_o_do_Servi_o__c =cont.Data_e_Hora_da_Solicita_o_do_Servi_o__c,
        Posicao__c = cont.Posicao__c ,
        Veiculo__c = cont.Veiculo__c,
        Solicitado_Por__c = cont.Solicitado_Por__c,
        Observa_o__c = cont.Observa_o__c,
        Defeito__c = cont.Defeito__c,
        Componente__c= cont.Componente__c,
        Status_do_Servi_o__c = 'Reagendar'

    cont.status_do_Servi_0__c = 'Reagendado';

  if(novoServicos.size()>0) {
    insert novoServicos;


Sylvio AvillaSylvio Avilla
Hello Rabindranath and JeffreyStevens,

Ok, I now that the code isn't following the good practice... but I would like to know why, the same code, has different behaviour in different accounts? Shouldn’t receive the error on both environments?

Thanks for the answer!