0

I'm trying to send email to list of users using batch class, but its throwing below error for few records.

Error:

System.EmailException: SendEmail failed. First exception on row 0; first error: UNKNOWN_EXCEPTION, List has more than 1 row for assignment to SObject: []

Please find my code below, for testing purpose i have hard coded my email address

Batch Class:

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

    global Integer recordsProcessed = 0;
    global database.querylocator start(Database.BatchableContext BC)
    {
        String ExcludeList = Label.ExcludeRecords;
        string Query = 'Select Id,Process_Name__c,Emails__c,Template_Name__c,From_Email__c FROM Custom_Object__c WHERE is_active__c = true';
        return Database.getQueryLocator(Query);
    }

    global void execute(Database.BatchableContext BC, List<Custom_Object__c> scope)
    {
         List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
         for(Custom_Object__c DQ:scope){

             String orgWideEmail  = DQ.From_Email__c;
             List<String> emails=new List<String>();
             if(DQ.Emails__c != null && DQ.Emails__c != '')
                 //emails = DQ.Emails__c.split(';');   
                 emails.add('Testchandra@gmail.com');
             EmailTemplate template = [SELECT id,HtmlValue FROM EmailTemplate WHERE DeveloperName = :DQ.Template_Name__c LIMIT 1];

             Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();    
             mail.setToAddresses(emails);   
             //Setting Org Wide Email
             if(orgWideEmail != null && orgWideEmail != ''){
                 OrgWideEmailAddress[] owea = [select Id from OrgWideEmailAddress where Address = :orgWideEmail limit 1];
                 if ( owea.size() > 0 ) {
                     mail.setOrgWideEmailAddressId(owea.get(0).Id);
                 }
             }else{
                 mail.setSenderDisplayName(''); 
             }
             mail.setBccSender(false);
             mail.setUseSignature(false);
             mail.setTargetObjectId(userinfo.getuseriD()); 
             mail.setTreatTargetObjectAsRecipient(false);
             mail.setTemplateId(template.Id);  
             mail.SaveAsActivity = false; 
             mails.add(mail);

        }
        system.debug(mails.size()+'size####Value'+mails);
        if(!Test.isRunningTest() && !mails.isempty()){
            try{
            Messaging.sendEmail(mails);
            }catch(System.EmailException ex){
                system.debug('getMessage #####'+ex.getMessage());
            }
        }
    }

    global void finish(Database.BatchableContext BC) {


    }
}

Executing with below code:

CustomObjectBatch  COB= new CustomObjectBatch ();

string Jobid= Database.executeBatch(COB, 1);
  • 2
    The SOQL query on Email Template must be causing this issue. Use List<EmailTemplate>. Though you're running batch with size of 1, it is not recommended to write SOQL in for loop. I can see there are two such SOQL in a single for loop. – Rohit Mourya Jan 7 '20 at 7:26
  • 1
    Can you post the complete exception you are getting? and the related code. – rahul gawale Jan 7 '20 at 7:30
  • Yes @RohitMourya the issue is with EmailTemplate, when i tried to open that email template it is showing below error : Error occurred trying to load the template for preview: List has more than 1 row for assignment to SObject. Please try editing your markup to correct the problem. – ncmouli Jan 7 '20 at 8:51
  • @ncmouli Try the updated the code written in below answer. – Rohit Mourya Jan 7 '20 at 9:17
0

I'm posting as an answer. There are couple of issues with your code.

  1. Email Template query is returning more than 1 record however you're storing it in a single instance.
  2. SOQL's written in for loop.

For temporary fix, get the list of Email Template and then use the [0] index record. Refer below code for reference:

global void execute(Database.BatchableContext BC, List<Custom_Object__c> scope)
    {
         List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
         List<EmailTemplate> templateList = [SELECT id,HtmlValue FROM EmailTemplate WHERE DeveloperName = :DQ.Template_Name__c LIMIT 1];
         //Setting Org Wide Email
         Id oweaId = null;
         String orgWideEmail  = DQ.From_Email__c;
         if(orgWideEmail != null && orgWideEmail != ''){
             OrgWideEmailAddress[] owea = [select Id from OrgWideEmailAddress where Address = :orgWideEmail limit 1];
             if ( owea.size() > 0 ) {
                 oweaId = owea.get(0).Id;
             }
         }
         if (templateList != null && templateList.size () > 0) {
            EmailTemplate template = templateList[0];
             for(Custom_Object__c DQ:scope){


                 List<String> emails=new List<String>();
                 if(DQ.Emails__c != null && DQ.Emails__c != '')
                     //emails = DQ.Emails__c.split(';');   
                     emails.add('Testchandra@gmail.com');


                 Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();    
                 mail.setToAddresses(emails);   
                 if (oweaId != null)
                    mail.setOrgWideEmailAddressId(owea.get(0).Id);
                else 
                    mail.setSenderDisplayName(''); 

                 mail.setBccSender(false);
                 mail.setUseSignature(false);
                 mail.setTargetObjectId(userinfo.getuseriD()); 
                 mail.setTreatTargetObjectAsRecipient(false);
                 mail.setTemplateId(template.Id);  
                 mail.SaveAsActivity = false; 
                 mails.add(mail);

            }
        }
        system.debug(mails.size()+'size####Value'+mails);
        if(!Test.isRunningTest() && !mails.isempty()){
            try{
            Messaging.sendEmail(mails);
            }catch(System.EmailException ex){
                system.debug('getMessage #####'+ex.getMessage());
            }
        }
    }

For the SOQL's written in for loop. Ideally it won't cause any issue for batch running with size of 1 but you would run out of limit with total number of email invocations allowed per day if your batch runs frequently and processed more number of records. It's better to bulkify your logic to process records of batch size of at least 200.

Refer this link for more details.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.