Skip to main content
3 of 3
Updated comment from support.
xn.
  • 2.5k
  • 20
  • 32

According to support, this is as designed, although it seems more like an oversight than a design decision to me. In any case, it should be documented.

From support:

The behavior that we see when we are using List is working as designed. Please find the detailed summary for the same below

-- The getDMLFieldName's return type is String[] whereas getDMLFields return type is Schema.sObjectField[]

which means the getDMLFields has to make a describe call to get the fields. The describe call looks something like follows

Account.sObjectType.getDescribe();

We need concrete SObject Types like Account or Opportunity to get this Describe call working. As Heterogeneous list List cannot be used to get the instance and map it to the describe call.

Hence kindly use Homogeneous List types like List or List to get the getDMLFields() working.

As a work-around, you can get the SObjectField if you keep a reference to the list of SObjects on which the failed DML operation was performed.

List<SObject> sobjects = new List<SObject>{new Account()};
try {
   insert sobjects;
} catch (DMLException e) {
  for (Integer i = 0; i < e.getNumDml(); i++) {
    // Get the list of field names, which may not be globally unique,
    // but will be unique for a single SObject
    List<String> fieldNames = e.getDmlFieldNames(i);
    // Get the SObjectType for the record that failed
    Integer insertIndex = e.getDmlIndex(i);
    Schema.SObjectType failedType =   sobjects[insertIndex].getSObjectType();
    for (String fieldName : fieldNames) {
      // Use the field name to get the SObjectField
      Schema.SObjectField fieldFromName = failedType.getDescribe().fields.getMap().get(fieldName);
      System.debug('SOBJECT FIELD FROM NAME');
      System.debug(fieldFromName);
    }
  }
}
xn.
  • 2.5k
  • 20
  • 32