Quantcast
Viewing all articles
Browse latest Browse all 40

Snapshotting objects in Salesforce with apex

A common issue that we have is a need to see information about Cases when it is created.  We do this to do some analysis about how a case changes (primarily to verify how good our automated tools are working).  To achieve this, we made a generic snapshot object that will store a JSON version of our data.  We chose JSON for it’s portability and it’s ability to dump into other systems.

The Object

To start out we’ll need a place to put this data, so we created the object with the following fields. Download object.

  • JSON_Data_{0-9}__cRequired – These are several LongTextAreas that stores json data
  • Object_Name__cRequired – This is the name of the object that was snapshotted
  • NameRequired – An auto number, just used for identification
  • Case__cOptional – This is used for our case specific snapshot to link a snapshot back to a specific case

Apex Class

Source Link

Let’s breakdown this class and explain what is happening.

  • Static Variables
    • JSON_DELIMITER - Because Salesforce strips whitespace from the end of textarea fields, we need to surround all of our split JSON data with a delimiter to force Salesforce to honor the data as we hand it in.
    • JSON_FIELD_SIZE - This is the size of our LongTextArea, minus the length of the delimiter twice (since we’re wrapping it)
    • JSON_FIELD_COUNT – This is the number of JSON_Data_*__c fields we have on our ObjectSnapshot__c object
    • JSON_FIELD_TEMPLATE – This is a String.format template to convert to the JSON_Data_*__c field we are storing the data in
    • SPARSE_JSON – If the JSON data should be trimmed prior to insertion
    • SNAPSHOT_VERSION – The “version” of the snapshot utils.  Used for auditing and stored with the snapshot
    • SNAPSHOT_*_LABEL - Text used to generate the map for the SNAPSHOT_INFO*
    • MSG_JSON_TO_LARGE – The message used if the JSON data exceeds the JSON_FIELD_COUNT multiplied by the JSON_FIELD_SIZE
    • SNAPSHOT_INFO – A map of data used to identify a successful snapshot.  This data is added to the snapshot for identification
    • SNAPSHOT_INFO_JSON_TO_LARGE – A map of data used to identify a unsuccessful snapshot due to the resultant data being to large to store in a single ObjectSnapshot__c object.
    • FIELD_BLACKLIST_MAP – This map of a set of strings is used to blacklist certain fields that should NEVER be fetched or attempted to be snapshotted.  For example, Case.lasevieweddate is a field that will throw a DML exception if the code attempts to do a .get(…) on that field.  Because of this, any items in the FIELD_BLACKLIST_MAP.get(objectName) will be removed from the objectDescription results.
  • Methods
    • getMapOfAllFields – This gets a map of all of the fields (minus the blacklisted fields) for a given object.  NOTE: This should not be called directly unless the objectDescription variable is already populated.  The getSnapshot method handles this request.
    • appendDelimiter - This appends the JSON_DELIMITER variable to the start and end of a string
    • jsonToSnapshot – This converts a map of String to Objects to ObjectSnapshot__c object
    • removeDelimiter – This removes the JSON_DELIMITER variable from the start and end of a string
    • snapshotToJSON – This converts an ObjectSnapshot__c object to JSON
    • getSnapshot – This takes an sObject and converts it to an ObjectSnapshot__c
    • createSnapshots – This takes a list of cases and converts them to an ObjectSnapshot__c and inserts them.

To create your own snapshots for a non Case object, just look at the implementation of createSnapshots(List<Case> cases) and tailor it towards your object.  Since the getSnapshot method uses Schema.DescribeSOjbectResult methods, it should be a matter of converting and then enriching the ObjectSnapshot__c object with any additional information you desire.  For example, we added a Case__c field that the Case’s Id is stored into, linking it back to the original object.

Usage

Using this is very simple after creating the createSnapshots method.  The following trigger calls our ObjectSnapshotUtils and tells it to create a snapshot for all of the new Cases.

Source Link

Future Plans

There are a couple of features I’d like to add to this to make it easier for others to consume. (In no particular order)

  • Better OO methods for this class.  Making it so you can extend a snapshot method and then do your enrichment (or overload an enrichment method).  This would allow you to do something like CaseSnapshotUtils implements ObjectSnapshotUtils and then call CaseSnapshotUtils instead
  • Better error handling JSON data being too long. Like putting more statistics in the SNAPSHOT_INFO_JSON_TO_LARGE map that gets inserted with the snapshot

Viewing all articles
Browse latest Browse all 40

Trending Articles