Dynamically Find Parent Objects in Apex Salesforce

What you will learn?

  • in Apex get all Parent object of any Salesforce Custom or Standard Object 
  • Get all parent objects in apex by passing object name dynamically
  • Get all parent objects of any specific object using apex. Example: Get all parent of Account Object
Apex Code

Here is a Apex method which take Child object as parameter and return map with Label and API name of all available parent objects.

public static Map<String, String> getParentObjects(String childObjectName) { 
    Map<String, String> mapParentObjects = new Map<String,String>();
    String SobjectApiName = childObjectName;
    Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
    for(Schema.SobjectField fldMap: schemaMap.get(SobjectApiName).getDescribe().fields.getMap().Values())
    {
        String customField = fldMap.getDescribe().getName();
        if(customField.endsWith('__c') && fldMap.getDescribe().getType() == Schema.DisplayType.REFERENCE)
        {
            List<SObjectType> refObjs = fldMap.getDescribe().getReferenceTo();
            String objectName = String.valueOf(refObjs[0]);
            mapParentObjects.put(getObjectLabel(objectName), objectName);
        }
    }
    return mapParentObjects;
}

Below method used to find Label of Salesforce Object.

Method To Get Object Label

public static String getObjectLabel(String objectName) { 
    Map<String, SObjectType> sObjects = Schema.getGlobalDescribe();
    return sObjects.get(objectName).getDescribe().getLabel();
}
Get Parent Object of Salesforce Account Object
public static Map<String, String> getParentObjects() { 
    Map<String, SObjectType> sObjects = Schema.getGlobalDescribe();
    Map<String, String> mapParentObjects = new Map<String,String>();
    for(Schema.SobjectField fldMap: Opportunity.SobjectType.getDescribe().fields.getMap().Values())
    {
        String customField = fldMap.getDescribe().getName();
        if(customField.endsWith('__c') && fldMap.getDescribe().getType() == Schema.DisplayType.REFERENCE)
        {
            List<SObjectType> refObjs = fldMap.getDescribe().getReferenceTo();
            String objectName = String.valueOf(refObjs[0]);
            mapParentObjects.put(getObjectLabel(objectName), objectName);
        }
    }
    return mapParentObjects;
}

How the code works

The method receives a child object name, reads all of its fields and collects the objects it looks up to, returning a Map of label to API name. A helper method finds the label of an object by its name.

Limits of this version

  • It only checks fields ending in __c, so standard lookups such as AccountId on Contact are missed.
  • It uses refObjs[0], so for a polymorphic field only the first object is returned.

Improved method

public static Map<String, String> getParentObjects(String childObjectName) {
    Map<String, String> parents = new Map<String, String>();
    Schema.SObjectType childType = Schema.getGlobalDescribe().get(childObjectName);
    if (childType == null) {
        return parents;
    }
    for (Schema.SObjectField fld : childType.getDescribe().fields.getMap().values()) {
        Schema.DescribeFieldResult d = fld.getDescribe();
        if (d.getType() == Schema.DisplayType.REFERENCE) {
            for (Schema.SObjectType refType : d.getReferenceTo()) {
                Schema.DescribeSObjectResult r = refType.getDescribe();
                parents.put(r.getLabel(), r.getName());
            }
        }
    }
    return parents;
}

This returns standard and custom parents, handles polymorphic fields, and avoids a crash when the object name is wrong. Fields such as CreatedById and OwnerId add User to the result, so remove it if you do not need it.

FAQ

How do I call it?
System.debug(getParentObjects('Contact')); returns Account, User and other parents of Contact.

Leave a Reply