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
Fintan MurphyFintan Murphy 

Apex NPE error

Hi, My apex code is giving the following error; translationStatusUpdate: execution of AfterUpdate caused by: System.NullPointerException: Attempt to de-reference a null object Trigger.translationStatusUpdate: line 28, column 1

Here is the code snippet;
 
trigger translationStatusUpdate on Translation__c (after insert, after update) {
    
    for(Translation__c trans:Trigger.new){
        if(trans.Translation_Status__c != null && trans.Case__c != null){
            //Case[] transCase = [SELECT Id, Translation_Status__c, CaseNumber FROM Case WHERE Id = :trans.Case__r.Id LIMIT 1];
            //String CaseId = transCase.get(Id);
                       
            if(trans.Translation_Status__c == 'Completed'){
                Boolean isComplete = TRUE;
                Translation__c[] otherTransCases = [SELECT Id, Translation_Status__c FROM Translation__c WHERE Case__c = :trans.Case__c AND Id <> :trans.Id];
                for(Translation__c otherTrans:otherTransCases){
                    if(otherTrans.Translation_Status__c <> 'Completed'){
                        isComplete = FALSE;
                        break;
                    }
                }
                if(isComplete){
                    //update new Case(Id = trans.Case__r.Id, Translation_Status__c = 'Completed');
                    trans.Case__r.Translation_Status__c = 'Completed';
                }
            }
            else{
                //update new Case(Id = trans.Case__r.Id, Translation_Status__c = trans.Translation_Status__c);
                trans.Case__r.Translation_Status__c = trans.Translation_Status__c;
            }
        }
    }
}

In general what is the best way to update the field on a parent object based on a child object? The Translation_Status__c field on Translation__c is a Master-Detail relationship.
 
Best Answer chosen by Fintan Murphy
MKRMKR
Hi,

First of all, you should bulkify your trigger. Currently there is SOQL query inside a loop which can easily cause issues with limits. However, to get the functionality implemented, I would do the following.

On line 2 define the cases that you want to update:
List<Case> casesToBeUpdate = new List<Case>();
Replace lines 18-19 with the following:
casesToBeUpdated.add(new Case(Id = trans.Case__c, Translation_Status__c = 'Completed'));
Replace lines 23-24 with the following:
casesToBeUpdated.add(new Case(Id = trans.Case__c, Translation_Status__c = trans.Translation_Status__c));
And after line 27, add the following line:
update casesToBeUpdated;
However, it is good to know that if several Translation__c records are updated in bulk, it could result in incorrect results (updating same case etc.).

Regards,
Mkr

All Answers

MKRMKR
Hi,

First of all, you should bulkify your trigger. Currently there is SOQL query inside a loop which can easily cause issues with limits. However, to get the functionality implemented, I would do the following.

On line 2 define the cases that you want to update:
List<Case> casesToBeUpdate = new List<Case>();
Replace lines 18-19 with the following:
casesToBeUpdated.add(new Case(Id = trans.Case__c, Translation_Status__c = 'Completed'));
Replace lines 23-24 with the following:
casesToBeUpdated.add(new Case(Id = trans.Case__c, Translation_Status__c = trans.Translation_Status__c));
And after line 27, add the following line:
update casesToBeUpdated;
However, it is good to know that if several Translation__c records are updated in bulk, it could result in incorrect results (updating same case etc.).

Regards,
Mkr
This was selected as the best answer
Fintan MurphyFintan Murphy
Hi Mkr,

Thank you for your quick reply. I have implemented your changes and also bulkified my trigger. It may not be the most efficient but it does the trick. W.R.T. several records being updated in bulk, you are correct however a bulk update isn't within our workflow and even if we do one the only important thing is that they don't get marked as complete when there is an incomplete translation, and that's not possible within this scheme.
 
trigger translationStatusUpdate on Translation__c (after insert, after update) {
    List<Case> casesToBeUpdated = new List<Case>();    
  	
    List<Translation__c> triggerTrans = new List<Translation__c>();
    List<Id> triggerCaseId = new List<Id>();
    for(Translation__c trans:Trigger.new){
        triggerTrans.add(trans);
    }
    for(Translation__c trans:triggerTrans){
        triggerCaseId.add(trans.Case__c);
    }
    
    Translation__c[] otherTransCases = [SELECT Id, Translation_Status__c, Case__c FROM Translation__c WHERE Case__c = :triggerCaseId];
    //Map<Id, Translation__c> transCasesMap = new Map<Id,Translation__c>([SELECT Id, Translation_Status__c FROM Translation__c WHERE Case__c = :triggerCaseId]);
    for(Translation__c trans:triggerTrans){
        if(trans.Translation_Status__c != null && trans.Case__c != null){
            if(trans.Translation_Status__c == 'Completed'){
                Boolean isComplete = TRUE;
                //Translation__c[] otherTransCases = [SELECT Id, Translation_Status__c FROM Translation__c WHERE Case__c = :trans.Case__c AND Id <> :trans.Id];
                List<Translation__c> otherTransThisCase = new List<Translation__c>();
                for(Translation__c otherTrans:otherTransCases){
                    if(otherTrans.Id <> trans.Id && otherTrans.Case__c == trans.Case__c){
                        otherTransThisCase.add(otherTrans);
                    }
                }
                for(Translation__c otherTrans:otherTransThisCase){
                    if(otherTrans.Translation_Status__c <> 'Completed' && otherTrans.Case__c == trans.Case__c && otherTrans.Id <> trans.Id){
                        isComplete = FALSE;
                        break;
                    }
                }
                if(isComplete){
                    casesToBeUpdated.add(new Case(Id = trans.Case__c, Translation_Status__c = 'Completed'));
                }
            }
            else{
                casesToBeUpdated.add(new Case(Id = trans.Case__c, Translation_Status__c = trans.Translation_Status__c));
            }
        }
    }
    update casesToBeUpdated;
}

Best,
Fintan.​​​​​​​