0

I have a requierment where i need to update product values daily based on product extendent values. I created a batch apex as article extended values are more. I am getting but still gettin 10001 DML exception. Here is the execute code i

public class Article_Extendet_Values_batch implements database.batchable<sObject>, Database.AllowsCallouts, Database.Stateful {
    
    
    private String query;
    
    public Article_Extendet_Values_batch() {
        
        query = 'select Price__c, Article_Name__c, IdExt__c, Article__c,'
            +'Class__c, ExcludeFromLoyalty__c, LoyaltyPoints__c,LoyaltyRefundable__c,Type__c from Article_Extendet_Values__c';
        
        //system.debug('query'+query);
        
    }
    
    public Database.QueryLocator start(Database.BatchableContext BC){
        return Database.getQueryLocator(query);
    }
    
    public void execute(Database.BatchableContext BC, List <Article_Extendet_Values__c> scope) {
        // system.debug('articleid1scope'+scope);
        list<SCArticle__c> articleList = new list<SCArticle__c>();
        set <id > artid= new set<id>();
        
        for(Article_Extendet_Values__c art : scope)
        {
            artid.add(art.article__c);
        }
        
        list<ScArticle__c> mappedarticle=[select id,class__c,ExcludeFromLoyalty__c,
                                          LoyaltyPoints__c,LoyaltyRefundable__c,type__c,idext__c from ScArticle__c where id =:artid];
        
        for( Article_Extendet_Values__c extval  :scope){
            
            
            for(SCArticle__C a : mappedarticle ){
                
                a.Class__c = extVal.Class__c;
                a.ExcludeFromLoyalty__c = extVal.ExcludeFromLoyalty__c;
                a.LoyaltyPoints__c = extVal.LoyaltyPoints__c;
                a.LoyaltyRefundable__c = extVal.LoyaltyRefundable__c;
                a.Type__c = extVal.Type__c;
                a.IdExt__c  = extVal.IdExt__c;
                
                // system.debug('class'+ a.Class__c);
                articleList.add(a);
            }
            
        }
        
        
        if(articleList.size() > 0) {
            try {
                update articleList ;
            }
            catch (DMLException e) {
                throw e;
            }
        }
        
        update articleList ;
    }
    
    
    public void finish(Database.BatchableContext BC) {
        
    }
    
}
3
  • The above-shared code does not contain any DML Statement, Looks like incomplete code. Please share the complete code. And Also What is the batch size ?! Dec 22, 2020 at 17:18
  • batch size is just 10
    – Vidya
    Dec 22, 2020 at 17:21
  • Seems likely artid could contain null and lead to this issue. Note also that it is not necessary to check for null before performing DML.
    – Adrian Larson
    Dec 30, 2020 at 15:22

1 Answer 1

6

There are lots of problems in this code. The proximate cause of the issue, however, appears to be in this section:

    list<ScArticle__c> mappedarticle=[select id,class__c,ExcludeFromLoyalty__c,
                                      LoyaltyPoints__c,LoyaltyRefundable__c,type__c,idext__c from ScArticle__c where id =:artid];
    
    for( Article_Extendet_Values__c extval  :scope){
        for(SCArticle__C a : mappedarticle ){
            // snipped
            articleList.add(a);
        }
        
    }
    
   update articleList ;

You are first running a query that may produce a large number of results. But then, you are iterating over two different sObjects in nested for loops and adding an item to articleList for every combination of an Article_Extendet_Values__c record and a SCArticle__C record.

That is almost certainly not what you should be doing - more likely, you should be correlating them based on the shared relationship on which your query is based - and it also multiplicatively increases the size of articleList, so that even fairly small query sets will hit 10,000 records.

You're also updating the same list twice because you've written the update DML both inside and outside guards that are totally useless and should be removed. That further doubles your DML limits usage.

Most likely, I think this batch should be written against SCArticle__c instead of Article_Extendet_Values__c, but that's just a guess based on what I see here.

You must log in to answer this question.

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