0

Ok...trying to write my first class and trigger and running into a wall that I can't seem to get over on my own.

Use case: on a custom object called manufacturer__c, when a field goes to "in Process" I need to query about 40k records to create a master detail against each to to both the Manufacturer record in the trigger and the queried records called Manufacturer Agreements.

Obviously my first attempt at a regular class failed at 10k records for too many DML. I actually considered that a victory since it was doing what I wanted.

So ok...now I need to do it as an Apex batch job. Fair enough. Converted my class to a batch class and my trigger to call the batch. The problem is I need to pass the Id of the manufacturer record from the trigger into the batch class to create the records and no mattaer what I do I can't seem to be able to and I get this error:

ERROR: Constructor not defined: [BlanketAgreementCreateApexBatch].(Id)

Trigger:

trigger Manufacturertrigger on Manufacturer__c (before insert, after insert, after update) {

    Id mfrid; **//Id to pass into batch class//**
    String dealstatus;
    Boolean bancreated;
    for(Manufacturer__c m: Trigger.new){
         mfrid=m.Id;
        dealstatus=m.Blanket_Deal_Status__c;
        bancreated=m.BansCreated__c;
}

    if(dealstatus == 'In Process' && bancreated == False) {

    BlanketAgreementCreateApexBatch bacab = new BlanketAgreementCreateApexBatch(mfrid); **//ERROR: Constructor not defined: [BlanketAgreementCreateApexBatch].<Constructor>(Id)//**

    Database.executeBatch(bacab);
     System.debug('the mfr id is' + mfrid);
    }

    }

Class:

global class BlanketAgreementCreateApexBatch implements Database.Batchable<SObject> {
    /**
        This batch apex job finds all blanket manufacturer agreement records and creates a 
        blanket agreement tied to the manufacturer that called this class from the trigger. 
        Requires asynchronous batch processing since there are more than 10k records to be created.
    */

    global Id mfrid;

    global Database.QueryLocator start(Database.BatchableContext BC) {
        // collect the manufacturer agreement records to be processed
            String query = 'SELECT Id FROM Manufacturer_Agreement__c WHERE Agreement_Type__c = \'Blanket Direct Deal\'';
            return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, List<Manufacturer_Agreement__c> manids) {

        // creates and inserts the blanket agreement records

        List<Blanket_Agreement__c> newbans = new List<Blanket_Agreement__c>();

        for(Manufacturer_Agreement__c man : manids )
        {Blanket_Agreement__c ban = new Blanket_Agreement__c ();
         ban.Manufacturer_Agreement__c = man.Id;
         ban.Manufacturer__c = mfrid;
         newbans.add(ban);
        system.debug('This manid is ' +man.Id);
         System.debug('the class mfrid is' + mfrid);
        }

        try {
            insert newbans;

        } catch(Exception e) {
            System.debug(e);       
        }

    }   

    global void finish(Database.BatchableContext BC) {

  }
}

Why do I get this error? How can I fix it?

1 Answer 1

2

As for your error:

constructor not defined

It's because you don't have a constructor defined in your batch class which accepts the argument mfrid being passed to it. To overcome this, you will need to define a constructor in your batch class, something as below:

global BlanketAgreementCreateApexBatch(Id mfrId) {
    this.mfrId = mfrId;
    ...
}

Now, more importantly that you have been able to transform it to a batch class, refer to this excerpt from the documentation and consider how you invoke the batch class from a trigger.

Use extreme care if you are planning to invoke a batch job from a trigger. You must be able to guarantee that the trigger will not add more batch jobs than the limit. In particular, consider API bulk updates, import wizards, mass record changes through the user interface, and all cases where more than one record can be updated at a time.

1
  • Thank you! I knew that it was something simple that I overlooked. And yes, I understand that care needs to be taken when launching a batch class from a trigger. It is a very limited use case to create thousands of records that users will only report on. Never create or edit on their own. So I should be safe with this implementation.
    – Bobbo
    Commented Aug 6, 2018 at 13:42

You must log in to answer this question.

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