In order to cover a specific requirement, I need to determine that the DML action of inserting the records of an sObject has been triggered through a batch.
The System class provides the isBatch() method to check if a batch Apex job invoked the excecuting code. This is not enough for my particular case, since the insert action can be triggered by different batches and I have to identify one of them in particular.
It seems that Apex doesn't provide a way to perform this check in a standard way.
One possible solution that after some testing seems like it might work.
- Having a static variable of
Stringtype in the batch class.
public static String batchClassName;
- Set the value of the static variable in the
executemethod of the batch.
public void execute(Database.BatchableContext bc, List<sObject> scope)
{
batchClassName = 'MyBatch';
//Logic that invoke insert dml action
}
Why set the value of the variable in the execute method?
First reason
Salesforce documentation indicates the following regarding using static methods and variables
A static variable is static only within the scope of the Apex transaction. It’s not static across the server or the entire organization. The value of a static variable persists within the context of a single transaction and is reset across transaction boundaries. For example, if an Apex DML request causes a trigger to fire multiple times, the static variables persist across these trigger invocations.
When the sObject trigger is fired it is in the same transaction as the batch, therefore the value of the static variable would not be null and would contain the string 'MyBatch'.
Second reason
If the variable is initialized in the constructor, the methods start, execute and finish get null value when accessing the variable.
So it seems that the value is not preserved between constructor, start, execute and finish methods.
What could be the limitations or risks of this approach (e.g., parallel executions of the batch)?
Edit
Edit to answer the question Why, specifically, do you need to ensure that a particular class is being invoked at runtime? and give a little more context.
Through an integration we receive massive loads of data that are stored in a custom sObject (ReceivedData__c) to be processed later. Among the custom fields contained in this sObject, the most important are:
Payload__c; contains the record data to be processed in JSON format.RelatedSOjbect__c; specifies to which sObject the receivedPayload__cbelongs.
The necessary logic for the bulk data to become a record of the corresponding sObject is processed in a batch. That batch relies on a helper class to perform the JSON transformation and insert the record on the corresponding sObject.
Due to an ongoing development it is necessary to identify when a record (only from one of the sOjbect received in the integration) has been inserted through this batch. In other words, the record must be identified as coming from the integration.
As a possible solution, a custom field of type checkbox/picklist could be set up at the sObject level. Then, in the batch logic, this field would be marked as coming from the integration.
The thing is that I am not convinced by the idea of having a custom field only for this functionality.
execute()method. Instance variables will survive the transaction boundary here.