I have a map variable that I am trying to pass into a batch class. This variable was created and populated in another batch class (which is why I can't just create it in the Start()
method of the second batch class).
The first batch class implments Database.Stateful
, in order to preserve the values I store in the map variable. Then, in the Finish()
method, I call the second batch class, passing the map variable, like so:
Database.executeBatch(new BatchClass(mapVariable));
The problem I'm running into is that I can't get the second batch class to recognize that I've passed this map to it. I've tried using the this.variable
assignment in the constructor class without being clear on its purpose, to no avail. Here's an idea of what that second batch class looks like now:
global class BatchClass implements Database.Batchable<sObject>{
String query = '[some SOQL query]';
global BatchClass(map<key, value> mapVariable) {
this.mapVariable = mapVariable;
}
global Database.QueryLocator start(Database.BatchableContext BC) {
return Database.getQueryLocator(query);
}
global void execute(Database.BatchableContext BC, List<sObject> scope) {
methodWhichUsesMapVariable();
}
global void finish(Database.BatchableContext BC) {}
In this format, the batch class doesn't recognize mapVariable
(says it does not exist). I've also tried making this batch class stateful, as well as declaring the mapVariable separately prior to the start() method, similar to the query
variable, which I thought might be necessary to do the this.mapVariable
assignment.
How can I make it so this Batch class can use the map variable I'm trying to pass to it? Thanks for your help and Merry Xmas/happy holidays!
EDIT:
So I got it to work (or at least save without error) by declaring the map variable before the start()
method, then assigning the passed variable to it, like so:
public static map<string, decimal> mapVariable = new map<string, decimal>();
global BatchClass(Map<string, decimal> sameMapVariableWithDiffName) {
mapVariable = sameMapVariableWithDiffName;
}
The interesting thing is, it didn't work until I specifically made the declared variable a static
variable. My understanding is that even though I made this batch class stateful
, static variables are reset with every batch. I don't know if this means I'm going to lose the map values after the first batch, but I'm about to find out!
If anyone knows why I could only get this to work by declaring the map static, I'd love to learn the reason!
EDIT 2:
First off, my 'solution' from EDIT 1 doesn't seem to be working (I think the map I'm using in my second batch class is actually an empty map, not what I tried to pass from the first batch class).
Anyway, in response to a request from Crop1645, here is the first part of the code for my batch class without any simplification or abstraction (which I had done in my first code example):
global class ClientMetrics_Stage6 implements Database.Batchable<sObject>, Database.Stateful {
//Stage 6
//Batches through the Usage Aggregate Data that was inserted in Stage 2.
//For each batch, pulls all* accounts' contracts and addendums in the system, determines matchings between them and the Aggregate usage data,
//and applies calculations using the contract data.
//*: Not ALL accounts, actually, just those who have been marked ready for contract review, and didn't have any results in their audit field.
//This stage takes a map passed in from stage 5, which has stored the total number of courses launched for each Account/month/product combo. This will be used by
//calcRecMMAC() to calculate the individual record MMAC (which is derived from the ratio of courses launched in that record vs courses launched for that account/month/product)
String query = 'SELECT ID, Account__c, Aggregate_Courses_Launched__c, Aggregate_Set__c, Country__c, Domain__c, MonthStart__c, YearStart__c, Product__c, Course_Name__c, Launch_Month__c ' +
'FROM Usage_Data_Aggregates__c WHERE Aggregate_Set__c = \'General Aggregated Usage\' AND Account__r.Contracts_Reviewed__c = TRUE AND Account__r.Audit_Field_Overlapping_Contracts__c =\'\'';
static map<string,string> productMap = new map<string,string>{'IPIMS BL Subtopic' => 'IPIMS Background Learning',
'IPIMS BL Topic' => 'IPIMS Background Learning',
'IPIMS AL' => 'IPIMS Action Learning',
'PO' => 'Petroleum Online',
'BEES' => 'Business Essentials',
'O&M' => 'Operations, Mntnc & Control Systems',
'HSE' => 'Health, Safety & Environment',
'N/A' => 'N/A'};
public static map<string, decimal> totalLaunchCountMap = new map<string, decimal>();
global ClientMetrics_Stage6(Map<string, decimal> tlcMap) {
totalLaunchCountMap = tlcMap;
}
global Database.QueryLocator start(Database.BatchableContext BC) {
return Database.getQueryLocator(query);
}
global void execute(Database.BatchableContext BC, List<sObject> scope) {
.... (I'll stop it here since there's a lot of methods called in the execute portion).
Crop, you're right that I'm getting the error at compile time (ie, when I attempt to save my code) except when using the code I show here, which uses a static declaration of the map and doesn't seem to work anyway. The error simply states that "variable: totalLaunchCountMap doesn't exist".
mapVariable
and also replacekey
andvalue
with their types in your real program; then include the exact error message you are getting (compile time error I presume)