I am getting following error when I call the batch from the trigger.
System.AsyncException: Database.executeBatch cannot be called from a batch start, batch execute, or future method.
My trigger code is as below:
trigger Certification_Data_Trigger on Certification_Data__c (before insert,after insert,before update,after update,before delete,after delete) {
if(Trigger.isAfter && !CertificationData_Helper.SKIP_TRIGGER_EXECUTION){
if(Trigger.isUpdate){
System.debug('in update');
List<Certification_Data__c> lstCertificates = new List< Certification_Data__c>();
for (Integer i=0;i<Trigger.new.size();i++) {
lstCertificates.add(Trigger.new[i]);
}
//Batch execution
if (lstCertificates.size() > 0 && lstCertificates.size() != 1)
Database.executeBatch(new UpdateCertificationBatch(lstCertificates));
}
}
}
And batch code is as below:
global class UpdateCertificationBatch implements Database.Batchable<sObject> {
List<Certification_Data__c > lstCertificate = new list<Certification_Data__c >();
public static Set < String > inActiveCertNameSet = new Set < String > {'Dev','Certified System Architect'};
public static Boolean SKIP_TRIGGER_EXECUTION = false;
//Constructor initialization
global UpdateCertificationBatch (List<Certification_Data__c > lstCertification) {
this.lstCertificate = lstCertification;
}
global Database.QueryLocator start(Database.BatchableContext BC) {
system.debug('lstCertificate ='+lstCertificate );
return DataBase.getQueryLocator([Select id, is_Active__c, Admin_Update_Date__c,Certification_Name__c,Cert_External_Id__c from Certification_Data__c ]);
}
//Execute Method.
global void execute(Database.BatchableContext BC,List<Certification_Data__c > lstCertification) {
List < Certification_Data__c > lstToUpdateAssociates = new List < Certification_Data__c > ();
Set < String > associateAdminUpdateDateSet = new Set < String > ();
String adminUpdateDate = '';
adminUpdateDate = lstCertificate[0].admin_update_date__c;
system.debug('adminUpdateDate ='+adminUpdateDate );
for (Certification_Data__c cert : lstCertification){
//adminUpdateDate matches then mark as active & mark the rest as inactive
if (adminUpdateDate.equalsIgnoreCase(cert.Admin_Update_Date__c) && !inActiveCertNameSet.contains(cert.Certification_Name__c)) {
cert.is_Active__c = true;
lstToUpdateAssociates.add(cert);
} else {
cert.is_Active__c = false;
lstToUpdateAssociates.add(cert);
}
}
if (!lsttoUpdateAssociates.isEmpty()) {
SKIP_TRIGGER_EXECUTION = true;
Schema.SObjectField fld = Certification_Data__c.Fields.Cert_External_Id__c;
Database.upsert( lsttoUpdateAssociates , fld, false);
SKIP_TRIGGER_EXECUTION = false;
}
}
global void finish(Database.BatchableContext BC) {
}
}
I am upsertting some certification records, but after upsertting, I am updating all the records with active/inactive status. The total no of records in the org is around 14000.