1

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 String type in the batch class.
public static String batchClassName;
  • Set the value of the static variable in the execute method 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 received Payload__c belongs.

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.

5
  • Static variables do not survive between transactions. I.e. if you set it in the initiating transaction, it will not be available when the batch class runs its execute() method. Instance variables will survive the transaction boundary here.
    – Derek F
    Commented Apr 7 at 18:47
  • 3
    This also sounds like an XY Problem. Knowing the specific class that is executed is an "implementation detail". You can write a test for this (and doing this in a test would likely be the appropriate way to go about this), but saying "Class X must be run" strikes me as fragile/tighly-coupled code. Doing this in normal, runtime logic doesn't make much sense to me. Why, specifically, do you need to ensure that a particular class is being invoked at runtime?
    – Derek F
    Commented Apr 7 at 18:50
  • 1
    Also good to remember that your users/clients should describe what to do, but not how to do it. Saying "You need to make sure class X is executed" is firmly in the realm of "how to do it".
    – Derek F
    Commented Apr 7 at 18:58
  • Regard your first comment @DerekF, yes, as Salesforce documentation points out static variables are not persistent between different transactions. Therefore I presume that the different batch methods are considered different transactions (in debug logs are different execution units).
    – Tzinm
    Commented Apr 8 at 7:21
  • if the incoming records are created by an integration, then wouldn't their createdBy user identify them as coming from the integration (which is what you really care about, not that a batch job is processing them later)?
    – cropredy
    Commented Apr 8 at 18:23

1 Answer 1

0

What could be the limitations or risks of this approach (e.g., parallel executions of the batch)?

The main limitation is that you won't know the class if it's a managed package.

Aside from that, it should work just fine for your own projects, so long as you make sure it's used consistently.

I'd suggest that it would probably be better to structure your code so that triggers can be selectively executed by way of a trigger framework. This way, the batch class itself can control the logic directly.

4
  • First of all thank you for your answer. Could you please expand the last paragraph a little more?
    – Tzinm
    Commented Apr 8 at 7:36
  • @Tzinm You can read various articles, like this one, that talk about what a trigger framework is and does. I'd recommend doing this so that your batch classes (and potentially other types of context) can work with the triggers to improve performance and orchestrate business logic.
    – sfdcfox
    Commented Apr 8 at 10:45
  • We have implemented a trigger framework similar to the one described in Trigger Pattern for Tidy, Streamlined, Bulkified Triggers Revisited. However, I still fail to recognize how this implementation can help us to identify the execution context.
    – Tzinm
    Commented Apr 8 at 13:49
  • @Tzinm you'd modify your trigger framework to have a way for the batch class to set a variable, which can then be used by your trigger handlers. Within a trigger, you only get basic execution connect, so it's up to you to arrange for more advanced information.
    – sfdcfox
    Commented Apr 8 at 14:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .