I wrote a batch process over the weekend that looks at a child record's date field and updates the corresponding date on the parent record. I originally wrote it as a bunch of if statements and then added the parent id and field to a list. When I ran the batch today I get an error in debug log:
"Duplicate id in list"
This makes me think I need to add the values from the if statements to a map where I can update the record once with all the fields that it needs instead of updating the record multiple times for each possible value.
Here is a snip of batch code I have, how can I adjust to update a record once instead of multiple times.
global void execute(Database.BatchableContext BC, List<Revenue_Pipeline_Schedule__c> revPipeSchedule) {
Map<Id, Revenue_Pipeline__c> revPipe = new Map<Id, Revenue_Pipeline__c>();
for(Revenue_Pipeline_Schedule__c rPS : revPipeSchedule){
if(rPS.Date__c == date.newinstance(2014,10,1)){ revPipe.put(rPS.Revenue_Pipeline__c, Oct2014__c=rPS.Amount__c));}
if(rPS.Date__c == date.newinstance(2014,11,1)){ revPipe.put(rPS.Revenue_Pipeline__c, Nov2014__c=rPS.Amount__c));}
if(rPS.Date__c == date.newinstance(2014,12,1)){ revPipe.put(rPS.Revenue_Pipeline__c, Dec2014__c=rPS.Amount__c));}
if(rPS.Date__c == date.newinstance(2015,01,1)){ revPipe.put(rPS.Revenue_Pipeline__c, Jan2015__c=rPS.Amount__c));}
if(rPS.Date__c == date.newinstance(2015,02,1)){ revPipe.put(rPS.Revenue_Pipeline__c, Feb2015__c=rPS.Amount__c));}
if(rPS.Date__c == date.newinstance(2015,03,1)){ revPipe.put(rPS.Revenue_Pipeline__c, Mar2015__c=rPS.Amount__c));}
.... 47 lines later
}
update revPipe;
Best Answer
Any time you need to use a map for de-duplication, the basic idea is:
However, in your case it is more complicated because you want to set multiple fields on the same record, so a scheme where you only use
put
won't work, because you will clobber your own updates. You can circumvent this problem, however, if you simply initialize all the keys first.A note on your absurdly long
if
chain: you can almost always reduce these unwieldy bits of logic to use aMap
. In this case, I would do aMap<Date, SObjectField>
that tells you where to put the data.Then your above code can further simplify to just a few lines: