0

I want to return a map containing the region and opportunity data called regOppMap and use it in another batch apex class called NewOppDistribution.

It has been confirmed that regOppMap is used in NewOppDistribution, but when batch is run multiple times in regionOppMap class, regOppMap does not contain all data. In my opinion, only the data from the last batch executed is included in the map.

How do I put all the data in regOppMap regardless of batch size and return this value for use in the NewOppDistribution class? I need your help.

The following is the code I wrote.

public class regionOppMap implements Database.Batchable<sObject>,Database.Stateful,Database.AllowsCallouts {

private String tier;
private String userSort;
private String distribution;
private String region1;
private String region2;
private Map<List<String>, Set<Id>> regOppMap;

public regionOppMap(String tier, String userSort, String distribution, String region1, String region2) {
    this.tier = tier;
    this.userSort = userSort;
    this.distribution = distribution;
    this.region1 = region1;
    this.region2 = region2;
   
}

public Database.QueryLocator start(Database.BatchableContext bc) {
    List<String> regionList1 = (region1 != null) ? region1.split(',') : null;
    List<String> regionList2 = (region2 != null) ? region2.split(',') : null;
    system.debug('regionList2:::'+ regionList2);
    
    String query;
    if(region1 != null && region2 != null){
        query = 'SELECT Id, Name, Region1__c, Region2__c FROM Opportunity where Region1__c Not IN :regionList1 AND Region2__c Not IN :regionList2 AND Tier__c = :Tier AND NewOpp__c = true';
    }else if(region1 == null && region2 != null){
        query = 'SELECT Id, Name, Region1__c, Region2__c FROM Opportunity where Region2__c Not IN :regionList2 AND Tier__c = :Tier AND NewOpp__c = true';
    }else if(region2 == null && region1 != null){
        query = 'SELECT Id, Name, Region1__c, Region2__c FROM Opportunity where Region1__c Not IN :regionList1 AND Tier__c = :Tier AND NewOpp__c = true';
    }else if(region1 == null && region2 == null){
        query = 'SELECT Id, Name, Region1__c, Region2__c FROM Opportunity WHERE Tier__c = :Tier AND NewOpp__c = true';
    }
    
    system.debug('query:::' + query);
     return Database.getQueryLocator(query);

}

 public void execute(Database.BatchableContext bc, List<sObject> scope) {
     
    GetRegionPartMap regionMapInstance = new GetRegionPartMap();
    Map<List<String>, List<String>> regionPartMap = regionMapInstance.getMap();
     
    regOppMap = new Map<List<String>, Set<Id>>();
  
    List<String> regionList1;
    List<String> regionList2;

    if(region1 != null) {
        regionList1 = region1.split(',');
    } else {
        regionList1 = null;
    }

    if(region2 != null) {
        regionList2 = region2.split(',');
    } else {
        regionList2 = null;
    }

    if(scope !=null){
        for (Opportunity opp : (List<Opportunity>)scope) {
            for (List<String> key : regionPartMap.keySet()) {
                if (key.contains(opp.Region1__c) || key.contains(opp.Region2__c)) {
                    if (!regOppMap.containsKey(key)) {
                        regOppMap.put(key, new Set<Id>());
                    }
                    regOppMap.get(key).add(opp.Id);
                }
            }
        }
    }
 }  

public void finish(Database.BatchableContext bc) {
    
    

    NewOppDistribution batch = new NewOppDistribution( tier,  userSort,  distribution,  region1,  region2, regOppMap);
    Database.executeBatch(batch, 1000);
    
}
}
2
  • 2
    Does this answer your question? How do static and member variables behave in a. stateful batch classes?
    – Nick C
    Commented Mar 31, 2023 at 0:03
  • @NickCook Thank you for your reply. I referred to what you told me. But I don't think I understood it properly because I wasn't good enough. I've already used Database.Stateful, but why is it returned without data being stacked
    – whytili
    Commented Mar 31, 2023 at 0:15

1 Answer 1

0

Your issue is in the execute()

regOppMap = new Map<List<String>, Set<Id>>();

You are reinstantiating the map in every execute(). Thus, batch 2 overwrites batch 1's map; batch 3 overwrites batch 2's map, ...

So, by the time you get to the finish() method:

NewOppDistribution batch = new NewOppDistribution( 
            tier,  userSort,  distribution,  region1,  region2, regOppMap);

regOppMap only has the last batch's data.

You should instantiate the map in either the start() method or directly as part of the batch class's construction.

1
  • Thank you for your answer. As you said, the problem was to instantiate the map again. Thank you for your kind reply.
    – whytili
    Commented Apr 3, 2023 at 23:50

You must log in to answer this question.

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