-2

Status: execution of BeforeUpdate caused by: System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: Case.ParentId Class.StatusTriggerHandler.StatusHandler: line 25, column 1 Trigger.Status: line 12, column 1

trigger Status on Case (before update)
{
    
    //Write the code in such a way that it can handle multiple data
    Case caseStatusBeforeChange = Trigger.old[0];
    Case caseStatusAfterChange = Trigger.new[0];
    System.debug('Old Status value =' +caseStatusBeforeChange);
    System.debug('New Status value =' +caseStatusAfterChange);
    
    if(caseStatusBeforeChange.id == caseStatusAfterChange.id && caseStatusBeforeChange.Status != caseStatusAfterChange.Status)
    {
        StatusTriggerHandler.StatusHandler(Trigger.new);
    }
    else
    {
            
    }
    if(Trigger.isUpdate)
    {
        if(Trigger.isBefore)
        {
            StatusTriggerHandler.StatusHandler(Trigger.new); 
        }
        
    }
}

public class StatusTriggerHandler
{
    public static void StatusHandler(List<Case> newcaseList)
    {
        //Storing all id's in a set
        Set<Id> caseIdSet = new Set<Id>();
        for(case c : newcaseList)
        {
            caseIdSet.add(c.Id);
        }
        System.debug('Here is =' + caseIdSet); 
        //we got our case id 00001034 
        System.debug('Here is Newcase List' + newcaseList);
      
        
        // case List  
        List <Case> caseList = [SELECT Id, Status FROM Case WHERE Id IN :caseIdSet];

        // Child Case List.
        List <Case> caseChildList = [SELECT Id,Status FROM case WHERE ParentId IN :newcaseList];
        Map<Id,Boolean> caseMap = new Map<Id,Boolean>();
        Map<Id,List<Case>> caseParentToCaseChildMap = new Map<Id,List<Case>>();
           
        for(Case case1 : [SELECT Id, Status FROM Case WHERE ParentId IN :newCaseList]) {
            if(caseParentToCaseChildMap.containsKey(case1.ParentId) ) {
                List<Case> CaseList1 = caseParentToCaseChildMap.get(case1.ParentId);
                CaseList1.add(case1);
                caseParentToCaseChildMap.put(case1.ParentId, CaseList1);
            } else {
                caseParentToCaseChildMap.put(case1.ParentId, new List<Case> {Case1});
            }
        }
        
        for(Id caseId:caseParentToCaseChildMap.keySet())
        {
            
            List<String> flagList = new List<String>();
            
            for(Case case2:  caseParentToCaseChildMap.get(caseId))
            {
               
                    if(case2.Status == 'Close'){
                        flagList.add('true');
                    }
                    else{
                        flagList.add('false');
                    }
                }   
            
            if(!flagList.contains('false')){
                 caseMap.put(caseId,true);
            }
            else{
                 caseMap.put(caseId,false);
            }
        
        }
        //List<Case> updatedCaseList = new List<Case>();
        //List<Case>errorCaseList = new List<Case>();
        if(caseMap.size() > 0){
            for(Case case3 : caseList){
                if(caseMap.containsKey(case3.Id) == true)
                {
                    if(CaseMap.get(case3.id) == True){
                        ((Case)Trigger.newMap.get(case3.Id)).Status = 'Close';
                    }
                    else{
                        // ((Case)Trigger.newMap.get(case3.Id)).
                        case3.addError('Child record is not Close');
                    }
                }
            }
        }
    }     
}
1
  • You are getting this error because you are using ParentId but haven't retrieved using SOQL. So add ParentId in SOQL that will solve this error
    – Dave
    Jun 21 at 12:14

2 Answers 2

2

The error is giving you pretty clear information here, you just need to take a little time to read it.

Taking the important part of it

SObject row was retrieved via SOQL without querying the requested field: Case.ParentId

So you're trying to use <case variable>.ParentId somewhere. The stack trace tells you this is line 25. Counting out the lines, that brings you to

if(caseParentToCaseChildMap.containsKey(case1.ParentId))

Yep, you certainly are using ParentId. Are you actually querying for it though? Let's look just a line upwards.

for(Case case1 : [SELECT Id, Status FROM Case WHERE ParentId IN :newCaseList]) {

Nope, you don't have ParentId in the SELECT clause. That means that you aren't querying that field, which in turn means that you can't use that field. ParentId does appear in a filter (i.e. a part of the WHERE clause, i.e. ParentId IN :newCaseList), but to be able to read/access ParentId outside of the query, it needs to appear in the SELECT clause.

Note that I specifically said if you want to read the ParentId field. If you were trying to write/set the ParentId field, you don't need to query for it.

Account a1 = [SELECT Id FROM Account LIMIT 1];
Account a2 = [SELECT Id FROM Account WHERE Id != :a1.Id LIMIT 1];

// we haven't queried the field before trying to read it
// this will result in an error
Id parentId = a1.ParentId;

// we can set fields without having queried them
a1.ParentId = a2.Id;

// after setting a field, we can read/access the value
// even if we didn't initially query for it
Id parentId2 = a1.ParentId;

Another way to think about it is in terms of where a1.ParentId is in the expression. Is it to the left of the = (i.e. an l-value) or to the right (i.e. an r-value)?
We don't need to query for a field to use it as an l-value
We do need to query for a field to use it as an r-value

1

The clue is in the error message. You're referring to fields you're not explicitly retrieving/

Change your SOQL from

SELECT Id, Status FROM Case

to

SELECT ID, Status, ParentID FROM Case

Then you should be ok. Also this is something that would be well suited for doing in a FLOW rather than APEX.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.