Tuesday, April 5, 2016

How to Get a List of Fields Set on an sObject in Apex

I recently had a requirement to dynamically determine what fields had been set or queried on a sObject, so that a comparison could be done on what was actually stored in Salesforce's Datastore.

Surprisingly, there's no way method on the sObject that let's you tell what's actually been queried or set. So without further ado, here's the method that I decided to use because it's much faster than doing a describe and catching every exception.



public class Utils {
    //Takes in an sObject and determines what values 
//have been queried or set on the page.
 public static Set<String> getFieldsSet(sObject obj)
    {
        if (obj == null)
            return new Set<String>();
             
  Map<String, Object> fieldValues = 
(Map<String, Object>) JSON.deserializeUntyped(JSON.serialize(obj));
         
   if (fieldValues.containsKey('attributes'))
      fieldValues.remove('attributes');
         
        return fieldValues.keySet();
    }
}

How to Dynamically Tell if a Salesforce Field Exists

I have been working on a lot of dynamic apex and soql. I had a requirement to develop a custom appexchange app that could be dynamically querying objects based on a mapping that the admin had supplied and had stored in custom settings.

Originally, I was querying to see if the field existed and returning true if a result was received but this ended taking a lot longer than doing a describe.

I wasn’t able to find any information on how to really tell if a field exists or not. Without further ado, doesFieldExist will return true if the object and field both exist. If the object has been removed and the code hasn’t caught that it will also return false. And finally, if the object exists but the field doesn’t it will return false.

public boolean doesFieldExist(String objName, string fieldName)
    {
   try {
     SObject so = Schema.getGlobalDescribe().get(objName)
.newSObject();
   return so.getSobjectType().getDescribe().fields.getMap()
.containsKey(fieldName);
        }
        catch(Exception ex) {}
         
        return false;
    }