0

I am currently developing the code that will update al the children accounts related to this parent account if this parent account gets 's updated.  gets updated. 

I have two questions:

  1. What could be a problem based on the error message a system puts out after account update attempt. Here is the error message:

Error:Apex trigger PTFT caused an unexpected exception, contact your administrator: PTFT: execution of BeforeUpdate caused by: System.NullPointerException: Attempt to de-reference a null object: ()

  1. is there any way I can create a variable for the records in account hierarchy rather than define each hierarchy like I have in my code.

I am quite new in apex coding and any help would be appreciated.  Please see my code below.

trigger PTFT on Account (before update) {
    if (trigger.isBefore){
       if (trigger.isUpdate || trigger.isInsert){
         list<Account> listAcc = new list <Account>();
              set<id> idAcc    = new set<id>();
               for(Account acc: trigger.new){ 
               Account oldAcc   = trigger.oldMap.get(acc.id);
               listAcc.add(acc);
               idAcc.add(acc.id);

               list <Account> acc2bUpdated = [select id, Name, CR_Parent_Fax__c, upaLevels__c,
                                     ParentId,
                                     Parent.Name,
                                     Parent.CR_Parent_Fax__c,

                                       Parent.ParentId,
                                       Parent.Parent.Name,                                    
                                       Parent.Parent.CR_Parent_Fax__c,

                                     Parent.Parent.ParentId,
                                     Parent.Parent.Parent.Name, 
                                     Parent.Parent.Parent.CR_Parent_Fax__c, 

                                     Parent.Parent.Parent.ParentId,
                                     Parent.Parent.Parent.Parent.Name, 
                                     Parent.Parent.Parent.Parent.CR_Parent_Fax__c,

                                     Parent.Parent.Parent.Parent.ParentId,
                                     Parent.Parent.Parent.Parent.Parent.Name, 
                                     Parent.Parent.Parent.Parent.Parent.CR_Parent_Fax__c

                                     from 

                                        Account
                                     where 
                                        ParentId != null
                                        AND  id IN: listAcc];



        if (!oldAcc.CR_Parent_Fax__c && acc.CR_Parent_Fax__c){
           if(acc2bUpdated.size() > 0) { 
              for(Account b: acc2bUpdated){
                    if( b.upaLevels__c == 2){           
                       b.Parent.parent.CR_Parent_Fax__c = true;
                    b.Parent.CR_Parent_Fax__c = true;
                }           
                else{
                    if(b.upaLevels__c == 3){

                         b.Parent.Parent.Parent.CR_Parent_Fax__c =true;
                         b.Parent.Parent.CR_Parent_Fax__c =true;
                         b.Parent.CR_Parent_Fax__c =true;

                    }       
                    else{
                        if( b.upaLevels__c == 4) {

                            b.Parent.Parent.Parent.Parent.CR_Parent_Fax__c = true;
                            b.Parent.Parent.Parent.CR_Parent_Fax__c = true;
                            b.Parent.Parent.CR_Parent_Fax__c = true;
                            b.Parent.CR_Parent_Fax__c = true;

                        }       

                            }                               
                         }                   
                     }               
                  }           
                }                   
              }
            }
          }


            system.debug(logginglevel.WARN, '^^^ event last modified: '+trigger.new[0].LastModifiedById);
            system.debug(logginglevel.WARN, '^^^ userinfo:  '+userinfo.getUserId());
1
  • 1
    Please use the formatting tools in the editor (particularly the {} code format button) to make your question readable. I fixed your formatting, but your next edit overwrote the changes.
    – David Reed
    May 25, 2018 at 0:25

1 Answer 1

3

Your code is backwards from the aim that you stated. You say that you would like to update child accounts based on a modification to the parent, but what your code is trying to do is update parents based on modification to their children.

That said, every single assignment statement in your code is capable of throwing a NullPointerException, and all of them for the same reason. Here's an example:

b.Parent.parent.CR_Parent_Fax__c = true;

You know for sure that b isn't null, because it's an sObject you queried. You seem to be relying on a field upaLevels__c to determine how many hierarchy levels exist above the Account. That's clearly not working, but I'll leave it aside because we don't know how you're deriving that value.

Returning to the line of code at hand, you're exposed to a NullPointerException because your code does not verify that each link in the chain of objects you're working with isn't null before you dereference it - you ask for one of its fields. Here, you get b.Parent, which is fine because we know b isn't null. But then you ask for that record's Parent attribute. If b.Parent were null, you'd get the exception right there. Then you ask again for an attribute of that object, b.Parent.parent.CR_Parent_Fax__c. If b.Parent.parent is null, there's another place you get the exception.

The normal way to avoid NullPointerException is to check for nulls before you dereference:

if (b.Parent != null) {
    // do something with b.Parent.SomeOtherField__c
}

In this case, though, the better solution (rather than trying to fix your current strategy) seems to me to be to write your code as you articulated it in the first place - from the top of the hierarchy down, instead of the bottom up. However, ultimately this is going to depend on exactly how you're using the account hierarchy, where users are going to be making changes, and how you need those changes to propagate.

If you want to go that top-down route, here's a skeleton that might be a useful starting point.

(Note that I've also addressed another issue here - your for loop encloses too much code. Your SOQL query should be outside the loop to correctly use the bulkification pattern you're using).

List<Account> acctsWithChildren;
List<Account> toUpdate = new List<Account>();

// Use a SOQL parent-child query to get accounts and immediate children.
acctsWithChildren= [SELECT Id, Name, CR_Parent_Fax__c,
                    (SELECT Id, Name, CR_Parent_Fax__c
                     FROM ChildAccounts)
                    FROM Account
                    WHERE Id IN :Trigger.newMap.keySet()];
// Loop over Accounts, find modifications, and use an inner loop to apply 
// those modifications to child accounts.
for (Account a : acctsWithChildren) {
    if (acc.CR_Parent_Fax__c && !Trigger.oldMap.get(acc.Id).CR_Parent_Fax__c) {
        for (Account child : a.ChildAccounts) {
            // What if this child account is also being updated?
            // Check for that case, and skip it.
            if (Trigger.newMap.containsKey(child.Id)) break;

            child.CR_Parent_Fax__c = true;
            toUpdate.add(child);
        }
    }
}

// Perform our updates.
update toUpdate;
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .