DML class

one class to hold all changes made during any APEX operation


what it is

I created a master class called the "DML Class" to hold all transactions that could occur during an APEX execution. The class consists of a couple map and list variables, a constructor, and three methods to perform the dml operations and populate the variables. The maps are used to keep track of records to be deleted and updated. They have a key - value pair of Id - SObject. There is a list of SObjects to populate with values that are to be inserted.

he three methods comprise of a map populator, a map retriever, and a dml operation method. They are very simple and powerful methods to help reduce the number of dml operations carried out in a APEX execution. The code for these methods is listed below.


code structure

public without sharing class DML_object
{
    private Map<String, Schema.SObjectType> objectTypeMap = Schema.getGlobalDescribe();
    public Map<Id, SObject> objectsToUpdate {get;set;}
    public Map<Id, SObject> objectsToDelete {get;set;}
    public List<SObject> objectsToInsert {get;set;}
    public Account acct {get;set;}
    public Opportunity opp {get;set;}

    public DML_object()
    {
        this.objectsToInsert = new List<SObject>();
        this.objectsToUpdate = new Map<Id, SObject>();
        this.objectsToDelete = new Map<Id, SObject>();
    }
    // Update (or insert if new) a record in the map
    public void UpdateRecord(String objectType, Id objectId, String fieldLabel, Object fieldValue)
    {
        SObject tempSObject = this.objectTypeMap.get(objectType).newSObject();
        tempSObject.put('Id', objectId);
        if(this.objectsToUpdate.containsKey(objectId)) tempSObject = this.objectsToUpdate.get(objectId);
        tempSObject.put(fieldLabel, fieldValue);
        this.objectsToUpdate.put(objectId, tempSObject);

        // Remove from objectsToDelete if applicable
        if(this.objectsToDelete.containsKey(objectId)) this.objectsToDelete.remove(objectId);
    }
    // Get a record from the map
    public Object GetRecordValue(String objectType, Id objectId, String fieldLabel, Object fieldValue)
    {
        SObject tempSObject = this.objectTypeMap.get(objectType).newSObject();
        tempSObject.put('Id', objectId);
        if(this.objectsToUpdate.containsKey(objectId)) {tempSObject = this.objectsToUpdate.get(objectId);}
        else {tempSObject.put(fieldLabel, fieldValue);}
        return tempSObject.get(fieldLabel);
    }

    // Sorting is required to reduce chunking errors
    public void SortAndUpsert()
    {
        // Sort and update the records
        this.objectsToUpdate.values().sort();
        if(!this.objectsToUpdate.isEmpty()) update this.objectsToUpdate.values();
        // Sort and insert the records
        this.objectsToInsert.sort();
        if(!this.objectsToInsert.isEmpty()) insert this.objectsToInsert;
        // Sort and delete the records
        this.objectsToDelete.values().sort();
        if(!this.objectsToDelete.isEmpty()) delete this.objectsToDelete.values();
    }
}

how to use it

I created the DML Class to be used in triggers, but it's methods can be applied to batch jobs and VFP controllers. Here is an example on how to call the methods in a trigger class method : 

// Insert new record
masterobject.ObjectsToInsert.add(
  new Account(
    Name = 'DML Class Account'
    Type = 'Prospect', 
    BillingStreet = '1234 Electric Avenue'
  )
);

// Update existing record
masterobject.UpdateRecord(
  'Account',        // Object type
  Account__c.Id,    // Record ID
  'OwnerId',        // Field label to update
  currentOwnerId    // Field value to use
);