[SalesForce] When is the constructor of a schedulable class invoked

I have a Class that implements the Schedulable interface and the constructor of this class initialises a variable with the value for the current month.

I found out that over the months, the value for this variable hasn't changed, so I was wondering what the order or execution is when it comes to Scheduled Apex.

My guess is that the class is constructed when the Scheduled Job is submitted, and then, every time it runs, it only calls the execute method, but it doesn't invoke the constructor on every run.

Could anyone let me know if I'm right or wrong?

Many thanks,
Julio

Best Answer

Suppose you have a Schedulable class and when it runs, the behavior of the execute() method doesn’t match what you expect. It looks like there’s memory of previous execute()s

Here is a specific example that distills the issue

public class MySchedulable implements Schedulable {

   Account[] accts = new List<Account>();

   public void execute(SchedulableContext sc) {
      accts.addAll([select id, name from Account where YTD_Total__c < 1000.0]);
      // do something interesting with this 
   }

You run the job weekly. You observe on week n, where n > 1, that Accounts are being processed that currently don’t have a YTD_Total__c < 1000. Accounts with YTD_Total__c > 1000 are being processed (?!?)

Explanation

  • When the job is scheduled, the class constructor is called (here, the implicit constructor) and the object variable accts is initialized empty.
  • On week 1, when execute() is called, the accounts with YTD_Total__c < 1000 as of week 1 are added to list accts.
  • On week 2, when execute() is called, the accounts with YTD_Total__c < 1000 as of week 2 are added to list accts.

Note that the class constructor is not reinvoked for each execute(). Hence, the accts list grows and grows. accts is never cleared.

Solution Reinitialize all object variables within the execute().

public class MySchedulable implements Schedulable {

   public void execute(SchedulableContext sc) {
      Account[] accts = new List<Account>();
      accts.addAll([select id, name from Account where YTD_Total__c < 1000.0]);
      // do something interesting with this 
   }
Related Topic