You need to sign in to do that
Don't have an account?
SeanGorman
Batch Apex Null Object Refernce Issue in Start()
Hi,
My first attempt at batching and I am coming up with an error. I have referenced other similar issues but I'm not getting anywhere.
Calling from a trigger I have a set of IDs that translate directly to User.Id.
Trigger:
trigger AddCurrtoTrans on lmscons__Transcript__c (after insert, after update) { /* adds a curriculum to a transcript when transcript is created need to call a future class to enter a new curriculum assignment record for each new user added in a given trigger context. */ set<id> setTrainees = new set<id>(); //string strQuery = ''; if (trigger.isInsert || trigger.isupdate) { // filter thoruugh the transcripts to find IDs (future classes cannot take cObjects) for (lmscons__Transcript__c lT : trigger.new) { setTrainees.add(lT.lmscons__Trainee__c); } system.debug('setTrainees ' + setTrainees); //CreateOnBoarding.addCurrtoTrans(setTrainees); //list<User> listTrainees = new list<User>([Select id from User where id in :setTrainees]); //RunAssignmentRulesBatch Create = new RunAssignmentRulesBatch(strQuery); database.executeBatch(new RunAssignmentRulesBatch(setTrainees), 100 ); } }
Class
global class RunAssignmentRulesBatch implements Database.Batchable<sObject>, Database.Stateful, Database.AllowsCallouts { global final string strQuery; global final set<id> Trainees; public RunAssignmentRulesBatch(set<id> Trainees) { system.debug('Trainees '+Trainees); if (system.Test.isRunningTest()) { this.strQuery = 'SELECT Id FROM User WHERE Id = \'' + UserInfo.getUserId() + '\' LIMIT 1'; } else { strQuery = 'SELECT u.Id, u.Department, u.Division from User u where u.ID in :Trainees and u.ContractorY_N__c = FALSE and u.IsActive=TRUE'; system.debug('strQuery constructor'+strQuery); } } global Database.QueryLocator start(Database.BatchableContext BC) { system.debug('strQuery start'+strQuery); return Database.getQueryLocator(strQuery); } global void finish(Database.BatchableContext BC) { } global void execute(Database.BatchableContext BC, list<User> Trainees) { system.debug('Trainees in execute '+Trainees); addAssignmentBatch(BC, Trainees); }
global void addAssignmentBatch(Database.BatchableContext BC, list<User> Trainees)
{
/*
curr.ass requires:
curriculum | this will be determined by the lmscons__Transcript__c.lmscons__Trainee__c
transcript | this is passed in by the trigger
trainess | this is passed in by the trigger
Trainees to transcript relationship | this is passed in by the trigger
Analytic Development On-boarding Program
Pre-Sales On-boarding Program (retired)
Product Development On-boarding Program
Professional Services (PS) On-boarding Program
PTO On-boarding Program
PTO On-boarding Program - General
Quality Assurance On-boarding Program
Sales On-boarding Program
Scores Delivery On-boarding Program
*/
system.debug('Trainees in addAssignmentBatch '+Trainees);
for (User trainee: Trainees)
logfile
14:16:47.047 (47406000)|METHOD_EXIT|[1]|RunAssignmentRulesBatch 14:16:47.047 (47640000)|SYSTEM_METHOD_ENTRY|[21]|System.debug(ANY) 14:16:47.047 (47698000)|USER_DEBUG|[21]|DEBUG|strQuery startSELECT u.Id, u.Department, u.Division from User u where u.ID in :Trainees and u.IsActive=TRUE 14:16:47.047 (47712000)|SYSTEM_METHOD_EXIT|[21]|System.debug(ANY) 14:16:47.047 (47739000)|SYSTEM_METHOD_ENTRY|[22]|Database.getQueryLocator(String) 14:16:47.049 (49583000)|SOQL_EXECUTE_BEGIN|[22]|Aggregations:0|SELECT u.Id, u.Department, u.Division from User u 14:16:47.051 (51344000)|EXCEPTION_THROWN|[22]|System.NullPointerException: Attempt to de-reference a null object 14:16:47.051 (51562000)|SYSTEM_METHOD_EXIT|[22]|Database.getQueryLocator(String) 14:16:47.051 (51628000)|FATAL_ERROR|System.NullPointerException: Attempt to de-reference a null object
Here is your problem:
The expression ':Trainees' is not valid dynamic SOQL. It is, however, valid APEX SOQL and easy to get confused. You need to blow apart the set<ID> trainees into parenthesized , comma separated, quoted ids like this: ('id1','id2','id3') before insertion into the strQuery string.
One way to debug this is to look at the result from:
and paste into SFDC Workbench or Eclipse IDE Schema and try and run the query. It has to be valid SOQL per the SFDC SOQL Guide
Kudos to you for putting debug statements in to try and figure this out yourself before reverting to the boards.
All Answers
Here is your problem:
The expression ':Trainees' is not valid dynamic SOQL. It is, however, valid APEX SOQL and easy to get confused. You need to blow apart the set<ID> trainees into parenthesized , comma separated, quoted ids like this: ('id1','id2','id3') before insertion into the strQuery string.
One way to debug this is to look at the result from:
and paste into SFDC Workbench or Eclipse IDE Schema and try and run the query. It has to be valid SOQL per the SFDC SOQL Guide
Kudos to you for putting debug statements in to try and figure this out yourself before reverting to the boards.
if(setTrainees.size() ==1)
{
strQuery = lT.lmscons__Trainee__c;
}
else
{
strQuery += ', ' +lT.lmscons__Trainee__c;
}
And BTW running a batch from a trigger is not a very good idea.
This was resolved by the previous poster. The problem was in the way I built the SOQL.
I understand the problems of batching out of a trigger but the volume of traffic in from the trigger is controlled by the integration and not expected to be more than 10-20 user records. The issue is in the amount of data that this causes to be written.
Let me say that promlem is not exactly in
There is nothing wrong with expressiong ':Trainees'. The problem is that it shoud to be saved in a variable first and it will work fine: