Got a little confused while trying to access a variable in my batch. I update a certain field on Contact based upon the LOB field as queried for in my initial query (line 2). However, when I later try to include that field in an if statement I get an error. Here's my code-

global class batch implements Database.Batchable<sObject>, Database.Stateful, Schedulable{
    global String query = 'SELECT ID, Policy_r.Product_Name_r.LOB__c FROM PAO__c WHERE Date__c = YESTERDAY';
    public Database.QueryLocator start(Database.BatchableContext BC) {       
        return Database.getQueryLocator(query);
    public void execute(Database.BatchableContext BC, List<PAO__c> scope) { 
    for(Custom__c custom : [SELECT Id, Contact__c, PAO__c, POA__r.field_i_need__c FROM Custom__c WHERE POA__c IN :scope])            
            updateConsMap.put(custom.Contact__c, custom);
    List<Contact> conList= new List<Contact>([SELECT Id, field_to_update__c FROM Contact WHERE Id IN :conIdSet]);
    if(!conIdSet.isEmpty()) {
        for(Contact con :conList) {
        /* line below is where i'm stuck! */
        if (Policy_r.Product_Name_r.LOB__c.Contains('Fixed'))
           con.field_to_update__c = updateConsMap.get(con.Id).Policy_Allocation_Option__r.Performance_Lock_Date__c;

        update conList;

The error I'm getting is Variable does not exist: Policy_r. What is the proper way to access this field to include it in the if statement?


1 Answer 1


First of all, relationship fields use double underscore


Your batchable execute() method receives a list of PAD__c which is where the Policy__r.Product_Name__r.LOB__c field can be found

But your for loop

for (Contact con: conlist) { ..}

is looping over contacts, not PAD__c and the only way you'll be able to reference a PAD__c is if you can associate a contact to a PAD__c.

The way one handles this is with a Map. You appear to be doing this in this line:

updateConsMap.put(custom.Contact__c, custom);

which appears to be a map of Custom__c's by ContactId

(my first suggestion is that all maps should be named by what they are: customsByContactId). This makes code so much easier to read and debug

You'll need a map padsById that you build as

Map<Id,PAD__c> padsById = new Map<Id,PAD__c> (scope);

So, now, in your for loop:

for (Contact con: conList) {
   Custom__c custom = customsByContactId.get(con.Id);
   if (padsById.containsKey(custom.PAD__c) &&
       padsById.get(custom.PAD__c).Policy__r.Product_Name__r.LOB__c.contains('Fixed') ) { ...}
  • i get the same error even when i add a second underscore
    – sfn00b
    Dec 15, 2020 at 19:47
  • more complete answer - updated
    – cropredy
    Dec 15, 2020 at 20:05
  • this is genius! thank you so much.
    – sfn00b
    Dec 15, 2020 at 20:20
  • hey question, don't i need to fill this map with a padsById.put(); somewhere prior to my loop?
    – sfn00b
    Dec 17, 2020 at 20:52
  • Map<Id,PAD__c> padsById = new Map<Id,PAD__c> (scope); populates the map -- and yes, before the for loop
    – cropredy
    Dec 17, 2020 at 20:53

You must log in to answer this question.

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