How to use Database Statful in batch apex

0 votes

I have a batch procedure that collects approximately 275,000 records by fund. I've set the batch size to the maximum of 200 people. As a result, when the batch runs, 1,380 batches are processed.

All of the funds must be processed by name. Let's say I have a fund called "Fund A." "Fund A" may appear 10 times in the initial batch of 200 records, and "Fund A" is rolled up and inserted for those 10 entries.

The following 200 records are processed, and "Fund A" may appear five times in those 200 records. For those 5 records, "Fund A" is rolled up and inserted.

This procedure continues until all batches have been processed, at which point I end up with numerous records for "Fund A."

The following is taken from the batch apex documentation:

Each batch Apex job execution is treated as a separate transaction. A batch Apex task with 1,000 records that is run without the optional scope argument is treated as five transactions with 200 records each.

If Database is specified. You can keep state across these transactions if the class definition is stateful. When working with a database Only instance member variables that are stateful keep their values between transactions. Static member variables do not persist across transactions and are reset. Counting or summarising records while they're processed is aided by maintaining state. Assume you worked in a position where you handled opportunity records.

You might use execute to create a method that tallied the totals of the opportunity amounts as they were processed.

If I understand correctly, I can merge "Fund A" into a single record that spans all batches and then insert it?

I'm attempting to make use of a database.

I'm trying to use stateful, but I'm receiving the following error:

First error: Insert failed. First exception on row 1 with id a28e0000000uvHYAAY; first error: INVALID_FIELD_FOR_INSERT_UPDATE, cannot specify Id in an insert call: [Id]

Here is my batch code:

global class ProductionAggregateRollupBatch implements Database.Batchable<sObject>, Database.Stateful {

public string query = 'select DBR__c, FundName__r.Name, FundName__r.Class__c, PurchasesPY__c, PurchasesPYTD__c, PurchasesYTD__c, RedemptionsPY__c, RedemptionsPYTD__c, RedemptionsYTD__c, AUM__c from Production_Aggregate__c';
global Map<String, Funds_Purchased__c> rollupMap = new Map<String, Funds_Purchased__c>();

global database.querylocator start(Database.BatchableContext BC)
{
    return Database.getQueryLocator(query);
}

global void execute(Database.BatchableContext BC, Sobject[] scope)
{
    Set<Id> dbrIds = new Set<Id>();

    for (Production_Aggregate__c pa : (List<Production_Aggregate__c>)scope) {
        dbrIds.add(pa.DBR__c);
    }

    Map<Id, List<Id>> dbrToContactMap = getDbrToContactMap(dbrIds);

    for (Production_Aggregate__c pa : (List<Production_Aggregate__c>)scope) {
        if(!dbrToContactMap.isEmpty() && dbrToContactMap.size() > 0) {
            if(dbrToContactMap.containsKey(pa.DBR__c)) {
                List<Id> contactIds = dbrToContactMap.get(pa.DBR__c);
                for(Id contactId : contactIds) {

                    String index = '' + new String[] {
                        '' + pa.FundName__r.Name,
                        '' + contactId
                    };                      

                    Funds_Purchased__c fundPurchased = rollupMap.get(index);

                    if(fundPurchased == null) {
                        fundPurchased = new Funds_Purchased__c();
                        rollupMap.put(index, fundPurchased);
                    }

                    fundPurchased.Fund_Name__c = pa.FundName__r.Name;
                    fundPurchased.DBR__c = pa.DBR__c;
                    fundPurchased.Contact__c = contactId;

Mar 16 in SalesForce by surbhi
• 3,810 points
377 views

1 answer to this question.

0 votes

Move your insert to the finish method:

global void finish(Database.BatchableContext BC) {
    if(rollupMap.size() > 0) {
        insert rollupMap.values();
    }
}


Your code has insert at the end of the execute method and would try 1380 times to call it. Insert presumably works the first time and assigns Ids to your in-memory objects. Your insert attempt on the second execution fails with an error message stating that you cannot insert with the given Ids. When you move insert to finish(), you'll only have to insert once after all of your execute iterations are finished.

answered Mar 17 by CoolCoder
• 4,360 points

Related Questions In SalesForce

0 votes
1 answer

Json response to be deserialized in Apex salesforce lightning

Because some fields in Apex are reserved ...READ MORE

answered Mar 2 in SalesForce by surbhi
• 3,810 points
1,030 views
0 votes
1 answer

How to Update RecordTypeId field in Lightning record form in salesforce?

A critical action that messes everything up ...READ MORE

answered Mar 3 in SalesForce by CoolCoder
• 4,360 points
1,262 views
0 votes
0 answers

How to Write the Test class for Salesforce Apex Aura Enabled class?

stuck in here to write a test ...READ MORE

Mar 15 in SalesForce by surbhi
• 3,810 points
338 views
0 votes
1 answer

How to find an element in Salesforce applauncher pop up using Selenium Webdriver?

Try if this works:- driver.findElement(By.xpath(".//p[text() ='Mar ...READ MORE

answered Mar 17 in SalesForce by CoolCoder
• 4,360 points
126 views
+2 votes
2 answers

Salesforce Interview questions

Here are some questions very important for ...READ MORE

answered Jan 11, 2019 in Career Counselling by Suresh
• 720 points
1,955 views
0 votes
1 answer

How to connect to salesforce from tableau?

Hi, follow these steps to connect to Salesforce: 1. ...READ MORE

answered Mar 25, 2019 in Tableau by Cherukuri
• 33,010 points
330 views
0 votes
1 answer

Power BI - Salesforce

Hi, Follow below steps: 1. Go to Data source. 2. ...READ MORE

answered Mar 25, 2019 in Power BI by Cherukuri
• 33,010 points
211 views
0 votes
1 answer

What is the best training for Salesforce ADM-201 Exam?

Hi @Vardhan, I took Edureka's Salesforce Training that covers all ...READ MORE

answered Jun 3, 2021 in Others by Jaya
• 140 points

edited Dec 22, 2021 by Soumya 240 views
0 votes
1 answer

How to add days to date time in Salesforce Apex?

Beware the DST issue! The "addDays" function ...READ MORE

answered Mar 15 in SalesForce by CoolCoder
• 4,360 points
1,384 views
0 votes
1 answer

How can i use select * in SOQL query in Salesforce?

SOQL is not the same as SQL. ...READ MORE

answered Mar 3 in SalesForce by CoolCoder
• 4,360 points
550 views
webinar REGISTER FOR FREE WEBINAR X
Send OTP
REGISTER NOW
webinar_success Thank you for registering Join Edureka Meetup community for 100+ Free Webinars each month JOIN MEETUP GROUP