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
Zach DelacroixZach Delacroix 

How to Get Parent ID

Hi Experts,

I have a simple question and I'm not sure why it's not returning correct data..

In my Class, I want to get the Parent Id of the Object. I'll need to traverse from Child, then Parent, and Parent of the Parent. Goes like this.

myObject > myObjectParent >MainParent.

myObject is where my trigger is, I want to be able to get the MainParent's ID and Here's how I do it. (The usual approach when I get Ids)

public class testClass {

    public void myMethod(List<myObject__c> myObjects){
       Set<Id> myObjectID = new Set<Id>();
    
       for(myObject__c myObject : MyObjects){
           myObjectID.add(myObject.MyParentObject__r.MainParentID);
       }
    }
}
Am I doing it wrong for this kind of situation? The code above returns Null so I can't use it in my query..

Can anyone please advise how to get the MainParent's ID?

Thank you!

-Zach

 
Best Answer chosen by Zach Delacroix
Pankaj_GanwaniPankaj_Ganwani
Hi Zach,

Since your method is being called from trigger, so you can get the ancestor upto 1 level only. For accessing the values for more than 1 levels you will have to perform SOQL.
 
public class testClass {

 

    public void myMethod(List<myObject__c> myObjects){

       Set<Id> myObjectID = new Set<Id>();

     

       for(myObject__c myObject : [select MyParentObject__r.MainParentID from myObject__c where Id IN : myObjects]){

           myObjectID.add(myObject.MyParentObject__r.MainParentID);

       }

    }

}

I am assuming that your trigger is fired on after insert or update.

All Answers

Anupam RastogiAnupam Rastogi
Hi Zach,

Not sure how you have ran the query for 'myObject', could not find it here. But the following piece of code returns the Account Id for an Opportunity Product (Opportunity Line Item) using the Opportunity object. This example is also having similar hierarchy like myObject > myObjectParent >MainParent (OpportunityLineItem > Opportunity > Account).

See if this helps, basically you need to have the Main Object Id in the select statement while retrieving the myObject records using the relationship.
 
OpportunityLineItem l = [select Id, Opportunity.AccountId 
                         from OpportunityLineItem 
                         where OpportunityId = '006U00000028H2Y'];

String AccId = l.Opportunity.AccountId;

System.debug('Output = ' + AccId);

BTW, was your other issue resolved?

Thanks
AR

If this reply helps solve your problem then please mark it as best answer.
Pankaj_GanwaniPankaj_Ganwani
Hi Zach,

Since your method is being called from trigger, so you can get the ancestor upto 1 level only. For accessing the values for more than 1 levels you will have to perform SOQL.
 
public class testClass {

 

    public void myMethod(List<myObject__c> myObjects){

       Set<Id> myObjectID = new Set<Id>();

     

       for(myObject__c myObject : [select MyParentObject__r.MainParentID from myObject__c where Id IN : myObjects]){

           myObjectID.add(myObject.MyParentObject__r.MainParentID);

       }

    }

}

I am assuming that your trigger is fired on after insert or update.
This was selected as the best answer
Zach DelacroixZach Delacroix
Wow that looks awesome Sir Pankaj :) Thank you for the explanation. I'll try this out and will let you know if it works. I'm actually going to use this on After Update. But will it matter whether I use it on After or Before? I didn't see any documentation about what you have mentioned where we can only traverse 1 level if I'm referencing my class to a trigger. If there's a documentation you can refer me that would be fantastic :) Thanks a lot! You guys are very helpful! -Zach
Pankaj_GanwaniPankaj_Ganwani
The above proposed solution is only valid for after insert or after update events since we can have Ids of the object records in after insert. In case of before insert, we don't have Ids of the object records(the trigger is acting upon).

In case of before insert you will have to go for following approach instead:

 
public class testClass { 

    public void myMethod(List<myObject__c> myObjects){

       Set<Id> myParentObjectId = new Set<Id>();
       Set<Id> myMainParentId = new Set<Id>();
     

       for(myObject__c myObject : myObjects){

           myParentObjectId.add(myObject.MyParentObject__c);

       }
        
        for(MyParentObject__c obj : [select MainParentID from MyParentObject__c where Id IN:myParentObjectId])
            myMainParentId.add(obj.MainParentID);
       
    }

}

I don't have any documentation at the moment to share with you, but you can practically try this in your dev org.
Zach DelacroixZach Delacroix
That's a lot just to get the MainParent's ID.. But that's all I need to be able to start completing my code. I'll have a lot more to ask in the future though :p

You're the best Pankaj! Hope to learn more from you :)

Thanks for the suggestions as well @Anupam Rastogi

Have a nice Day!

-Zach
Seema KhattarSeema Khattar
Hi Pankaj,

I was going through your answer and have a question. When you say "you can get the ancestor upto 1 level only", I expected it to mean that I can at least retrieve the fields of parent one level up without using SOQL i.e. below should give me at least the value of grandparent Id (assuming it is stored at parent level):

Id gpId = myObject.MyParentObject__r.MainParentID;

Can you please explain.

 
Pankaj_GanwaniPankaj_Ganwani
Hi Seema,

Id gpId = myObject.MyParentObject__r.MainParentID;
As per your above code statement, we are accessing the parent at 2nd level. The 1st level means that myObject.MyParentObject__c. In other words, just one above is 1st level and one above of 1st level is 2nd level and so on.

We cannot retrieve any field value at parent level in trigger except Id(ie. myObject.MyParentObject__c). After dot(.) we consider the levels and these are determined by the lookup fields.

Example: Object A is the parent of Object B and Object C is child of Object B. Now, we want to access the grandparent at object C, then we will use 2nd level formula like C.B.A. C.B will be first level and C.B.A will be second level.

Please let me know if this makes sense.

Thanks,
Pankaj
Seema KhattarSeema Khattar
Yes.. that explains it..

Thanks!
Seema