1

I having an issue when I trying to pass params from one batch to another (BatchA --> BatchB).

In the constructor of BatchB, I can see the values that I passed from BatchA, but in the execute method, Only the first chunk is having the values but from the second to the last, it's not.

What can be the issue??

Batch A :

 global class BatchA implements Database.Batchable<sObject>, Database.Stateful {
    Map<Sobject,Set<String>> pMap = new Map<Sobject,Set<String>>();
    Set<String> bigSet = new Set<String>();
    String query;

    global BatchA() {

    }

    global Database.QueryLocator start(Database.BatchableContext BC) {
        query = 'SomeQuery FROM SobjectA';

        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, List<SobjectA> scope) {
            Set<String> intrersts;
            for(Sobject ifr : scope){
                intrersts = new Set<String>();
                intrersts.add(ifr.SomeField_1__c);
                intrersts.add(ifr.SomeField_2__c);
                intrersts.add(ifr.SomeField_3__c);

                bigSet.addAll(intrersts);

                porposalToInternstsMap.put(ifr,intrersts);




           }  




    } 

    global void finish(Database.BatchableContext BC) {

        Id batchJobId = Database.executeBatch(new BacthB(this.pMap,this.bigSet), 200);
    }

BatchB :

global class BatchB implements Database.Batchable<sObject> , Database.Stateful {
    Map<SobjectA,Set<String>> pMap  = new Map<SobjectA,Set<String>>();
    String query;
    List<String> bigSet = new List<String>();
    // Map<ContactDetails,Set<Call_for_proposal__c>> contactToProposal = new Map<Contact,Set<Call_for_proposal__c>>();

    global Matching_Proposal_Intersts_Batch(Map<Sobject,Set<String>> interstedMap,set<String> bigSet) { 
        this.bigSet.addAll(bigSet);
        this.pMap .putAll(interstedMap);

        System.debug('pMap   => ' + this.pMap ); // Work - give me exactly what I passed from the first batch.
    }

    global Database.QueryLocator start(Database.BatchableContext BC) {  

        this.query = 'SomeQuery FROM SobjectB';
        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, List<SobjectB> scope) {

        for(SobjectB b : scope){

            for(SobjectA curPmap : pMap.keySet()){

                System.debug('pMap values   => ' + this.pMap.values() ); // Work only in the first chunk! From the Second chunk to the last the Values of the Map Is null .
                System.debug(pMap.get(curPmap)); // in the first chunk it work fine! in the second to the last chunck It getting null.
            }

        }
    }

    global void finish(Database.BatchableContext BC) {

    }

I tried to send A Map of Map<Id, Set<String>> In BatchA and retrive the records in a SOQL inside the contructor of BatchB, If the problem is in with the hashing when Sobject is a key in a map - But the issue is remaining. Thanks!

8
  • See the answer by Phil W to the previous version of this question salesforce.stackexchange.com/questions/267695/…. The normal approach is to use the Id of an SObject not the SObject itself as the key.
    – Keith C
    Commented Jun 30, 2019 at 11:22
  • Yes, as I wrote in the end of the question - I tried that also
    – Salvation
    Commented Jun 30, 2019 at 11:23
  • OK. I suggest you post a more complete version of the failing code (the version using Id as a key).
    – Keith C
    Commented Jun 30, 2019 at 11:27
  • Thanks! you right, I will change this question right away
    – Salvation
    Commented Jun 30, 2019 at 11:30
  • 1
    As I mentioned in my other question answer, the key depends entirely on the content of the SObject, so if you query the data differently in the two batches (even just one field extra or different) then the SObjects won't match and it won't be recognized as the key. Use some simple, immutable vale if at all possible, such as the ID. IDs for records do not change. Of course a newly created SObject that hasn't yet been inserted won't have an ID, so only use ID as the identity after you have inserted the SObject (and where you queried the ID appropriately).
    – Phil W
    Commented Jul 1, 2019 at 7:00

0

Browse other questions tagged .