• sebastiangnagnarella
  • NEWBIE
  • 70 Points
  • Member since 2013

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 2
    Questions
  • 7
    Replies

Considering I have to run several different batch processes in my org and the governance limit allowing only 5 queued batch processes at a time, I took this idea and i tried to take it to the next level to avoid using a custom setting to store the current JobId. My idea was simple. In a nutshell I was going to keep the JobId for that execution inside the Apex Batch, and having the finish method using that value to abort the scheduled job

global with sharing abstract class INS_aOrchestratedBatch implements Database.Batchable<sObject> {
    
    protected final integer BATCHS_INTERVAL_MIN = 2;
    
    private List<INS_aOrchestratedBatch> batchProcessOnQueue;
    private Map<string, string> parameters;
    protected string query;
    protected string name;
    
    
    global string getName(){
        return name;
    }
    
    global Id jobId{set;get;}
    
    
    global INS_aOrchestratedBatch(List<INS_aOrchestratedBatch> abatchProcessOnQueue, Map<string, string> aparameters, string pname){
        System.debug('Building INS_aOrchestratedBatch');
        
        batchProcessOnQueue = abatchProcessOnQueue;
        parameters = aparameters;
        name = pname;
    }
    
    global virtual Database.QueryLocator start(Database.BatchableContext BC){
        return Database.getQueryLocator(query);  
    }
    
    global abstract void execute(Database.BatchableContext BC, List<sObject> scope);
    
    global virtual void finish(Database.BatchableContext BC){
        sendJobStatus(BC);
        cancelPreviousJobSchedule(jobId);
        scheduleNextBatch(BATCHS_INTERVAL_MIN);
    }
    
    protected virtual string scheduleNextBatch(Integer minutesAfter){
        
        
        
        string returnJobId;
        
        if(batchProcessOnQueue.size() > 0 ){ 	
            integer nextBatchIndex = batchProcessOnQueue.size() - 1;
            INS_aOrchestratedBatch nextBatch = batchProcessOnQueue.remove(nextBatchIndex);
            
            DateTime n = datetime.now().addMinutes(minutesAfter);
            String cron = '';
            
            cron += n.second();
            cron += ' ' + n.minute();
            cron += ' ' + n.hour();
            cron += ' ' + n.day();
            cron += ' ' + n.month();
            cron += ' ' + '?';
            cron += ' ' + n.year();
            
            INS_OrchestratedBatchScheduler scheduler = new INS_OrchestratedBatchScheduler(nextBatch);
            
            
            
            returnJobId = System.schedule('Notification Batch - ' + nextBatch.Name , cron, scheduler);
            system.debug('scheduleNextBatch --------->'  + returnJobId);
            //We setup the jobId on the same class so it cancel itself at the end
            nextBatch.jobId = returnJobId;
        }
        
        return returnJobId;
        
    }
    
    private virtual void cancelPreviousJobSchedule(Id jobId){
        if(jobId != null){
		System.abortJob(jobId);
        }
    }
    

}

 

 

 

You will find out that that I am using a list of chained process and  also a wrapper to schedule, but that doesn't make any difference to understand the problem. The interesting part is in this line :

 

            returnJobId = System.schedule('Notification Batch - ' + nextBatch.Name , cron, scheduler);
            system.debug('scheduleNextBatch --------->'  + returnJobId);
            //We setup the jobId on the same class so it cancel itself at the end
            nextBatch.jobId = returnJobId;

 Where I schedulle the job and then I tried to setup a properly so it can auto abort the job in the finish.

However when the class hits the finish, the jobId property is null, My idea here is that when salesforce queues the class in the scheduller, the instance is copied somewhere else and you cannot modify the values of what is already queued. i also tried with a static variable with the same results.

I ended up just queryng the CronDetails (only available in W'14)  together with the  CronTrigger object, to get the job Id based on my Schedule name.

 

Any ideas about this behavior of schedulled classes? I am curious how it works as it is not documented.

 

Thanks

Hi,

 

Does anybody know if there is a way to check if the user is currently in a call?

 

I checked sforce.console.cti.getCallObjectIds (javascript) but I think it only works if the CTI adapter creates a Call Task.

 

Any idea?

 

The ideal solution would be to check a global Apex variable.

Hi,

 

I've got a batch job that works well in manual testing, processing multiple records in each batch without any issues. However my unit test fails if I set the scope greater than just 1 record with a "System.UnexpectedException: Error processing messages". I'm stumped, does anyone know what this cryptic exception means?

 

Thanks a lot,

Mike

Can u please tell me the diff btn Iterable and Database.Querylocator() in Batch apex?

Just tell me few words.

 

Thanks

below is the code that i have tried to do the cloning.

 

Account acc=new  Account(Name='ACC');
insert acc;
Opportunity CloneOpp= new Opportunity(Name='CloneOpp',AccountId=acc.id,Amount=222,StageName='xyz',CloseDate=System.today(),h1newContractEndDate__c=System.today());
 insert CloneOpp;

 Opportunity colned=CloneOpp.clone(true,false);
      
        
  system.debug('*Id=*'+colned.id);
  system.debug('source id='+CloneOpp.id);
 system.debug('*name*'+colned.Name);
  system.debug('opp='+CloneOpp.Name);


     colned.Name='TestNew';

   system.debug('*name after update*'+colned.Name);
   system.debug('Source opp Name='+CloneOpp.Name);//this should be print TestNew but it prints CloneOpp

 

apex guide says-" If "opt_IsDeepClone" argument set to false, the method creates a reference to
the original sObject. Consequently, if you make changes to a field on the cloned sObject, the original
sObject is also affected".

 

 

please guide if any one has answer of this ..

I've created a master-detail relationship field on a custom child object, looking to a custom parent object. When I create the child record, of course the master-parent record is required, and I'm then able to save the child record.

 

But once the child record has been saved, the master-detail lookup field to the parent record is now locked - I'm unable to edit the master-parent record, even though I had edit read-only field rights.

 

Any ideas would be great, thanks!

Hi everybody,

 

I'm working on a new trigger in the UPDATE event and we need to identify specifically which fields of that object have changed its values. I know there is a comparison between trigger.new and trigger.old objects but as I can see, it is required to hardcode the field name to know what we are asking for.

 

Is it possible that catch that behavior dynamically? 

 

Regards,

 

Wilmer

  • August 24, 2009
  • Like
  • 0