+ Start a Discussion
Singh 837Singh 837 

Apex Trigger to auto populate look up field for multiple records

down vote favorite
I am trying to update a lookup field(Benefit_ID in Customer object) with the below code, The code works fine for single record but it is failing for multiple records:
Error: "caused by: System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, "
trigger updatelookupfield_Customer on Customer__c (before insert,before update) {
    Set<String> Bundle = new Set<String>();

    for (Customer__c Cust : Trigger.new) {
        Bundle.add(Cust.Bundle__c);
    }
List<Benfit__c> BenfitList = [SELECT id, Bundle__c FROM Benfit__c WHERE Bundle__c IN :Bundle];

    Map<String, Benfit__c> ASSIGN_BENEFIT = new Map<String, Benfit__c>();

    for (Benfit__c c : BenfitList) {
        ASSIGN_BENEFIT.put(c.Bundle__c, c);
    }

    for (Customer__c o : Trigger.new) {
              if (o.Bundle__c != null) {
            o.Benefit_ID__c = ASSIGN_BENEFIT.get(o.Bundle__c).id;
        }
        else {
            o.Benefit_ID__c = null;
        }
    }
    }
Just to highlight i am using multiple triggers on this object, not sure that is the reason for this issue.
 
Best Answer chosen by Singh 837
Abdul KhatriAbdul Khatri
I really don't see any issue in the code and the exception you  are showing doesn't look like issue in this code. There is a possibility you are getting this issue because of any other trigger failure. My thought is you are using this while inserting and updating the customer. That steps should be working fine and code is also bulkify to handle multiple records.

Please share some more details from the log.

I just made a little couple of improvements
  1. Null check
  2. stop recurring call whenever customer updates happen

Please take a look
 
trigger updatelookupfield_Customer on Customer__c (before insert,before update) {

    Set<String> Bundle = new Set<String>();

    for (Customer__c Cust : Trigger.new) {
        
        if(Cust.Bundle__c == null) continue;
        
        if(trigger.isInsert || (trigger.isUpdate && (Cust.Bundle__c != trigger.oldMap.get(Cust.Id).Bundle__c)))
        
        Bundle.add(Cust.Bundle__c);
    }
	
    if(Bundle.isEmpty()) return;
    
    List<Benfit__c> BenfitList = [SELECT id, Bundle__c FROM Benfit__c WHERE Bundle__c IN :Bundle];
	
    if(BenfitList.isEmpty()) return;
    
    Map<String, Benfit__c> ASSIGN_BENEFIT = new Map<String, Benfit__c>();

    for (Benfit__c c : BenfitList) {
        ASSIGN_BENEFIT.put(c.Bundle__c, c);
    }

    for (Customer__c o : Trigger.new) {
        
		if (o.Bundle__c != null) {
            o.Benefit_ID__c = ASSIGN_BENEFIT.get(o.Bundle__c).id;
        }else {
            o.Benefit_ID__c = null;
        }
    }
}


 

All Answers

Abdul KhatriAbdul Khatri
I really don't see any issue in the code and the exception you  are showing doesn't look like issue in this code. There is a possibility you are getting this issue because of any other trigger failure. My thought is you are using this while inserting and updating the customer. That steps should be working fine and code is also bulkify to handle multiple records.

Please share some more details from the log.

I just made a little couple of improvements
  1. Null check
  2. stop recurring call whenever customer updates happen

Please take a look
 
trigger updatelookupfield_Customer on Customer__c (before insert,before update) {

    Set<String> Bundle = new Set<String>();

    for (Customer__c Cust : Trigger.new) {
        
        if(Cust.Bundle__c == null) continue;
        
        if(trigger.isInsert || (trigger.isUpdate && (Cust.Bundle__c != trigger.oldMap.get(Cust.Id).Bundle__c)))
        
        Bundle.add(Cust.Bundle__c);
    }
	
    if(Bundle.isEmpty()) return;
    
    List<Benfit__c> BenfitList = [SELECT id, Bundle__c FROM Benfit__c WHERE Bundle__c IN :Bundle];
	
    if(BenfitList.isEmpty()) return;
    
    Map<String, Benfit__c> ASSIGN_BENEFIT = new Map<String, Benfit__c>();

    for (Benfit__c c : BenfitList) {
        ASSIGN_BENEFIT.put(c.Bundle__c, c);
    }

    for (Customer__c o : Trigger.new) {
        
		if (o.Bundle__c != null) {
            o.Benefit_ID__c = ASSIGN_BENEFIT.get(o.Bundle__c).id;
        }else {
            o.Benefit_ID__c = null;
        }
    }
}


 
This was selected as the best answer
Maharajan CMaharajan C
Hi Singh,

Add one more checking.

Please check the Map contains the key otherwise it will throw the exception:

trigger updatelookupfield_Customer on Customer__c (before insert,before update) {

    Set<String> Bundle = new Set<String>();

    for (Customer__c Cust : Trigger.new) {
        
        if(Cust.Bundle__c == null) continue;
        
        if(trigger.isInsert || (trigger.isUpdate && (Cust.Bundle__c != trigger.oldMap.get(Cust.Id).Bundle__c)))
        
        Bundle.add(Cust.Bundle__c);
    }
    
    if(Bundle.isEmpty()) return;
    
    List<Benfit__c> BenfitList = [SELECT id, Bundle__c FROM Benfit__c WHERE Bundle__c IN :Bundle];
    
    if(BenfitList.isEmpty()) return;
    
    Map<String, Benfit__c> ASSIGN_BENEFIT = new Map<String, Benfit__c>();

    for (Benfit__c c : BenfitList) {
        ASSIGN_BENEFIT.put(c.Bundle__c, c);
    }

    for (Customer__c o : Trigger.new) {
        
        if (o.Bundle__c != null && ASSIGN_BENEFIT.containsKey(o.Bundle__c)) {
            o.Benefit_ID__c = ASSIGN_BENEFIT.get(o.Bundle__c).id;
        }else {
            o.Benefit_ID__c = null;
        }
    }
}

Can you please Let me know if it helps or not!!!

If it helps don't forget to mark this as a best answer!!!


Thanks,
Raj
Raj R.Raj R.
Are you 100% positive that your trigger is bulkified?
List<Benfit__c> BenfitList = [SELECT id, Bundle__c FROM Benfit__c WHERE Bundle__c IN :Bundle];
The moment this return more than 50,000 records, you will reach governor limits (https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm). Also have you verified that this does not generate a recursive call?
Abdul KhatriAbdul Khatri
Hi Raj,

I think you are mixing the bukification of the code with the Limits to avoid Governor Limits. Please read this article for your knowledge. From the Bulkify approach the code is 100% bulkified. Yes we can the LIMIT in the SOQL to avoid Governor but if you expect that level Data Transaction on every trigger than we need to change the approach of going Batch. I hope this will clarify your concepts.

https://developer.salesforce.com/page/Apex_Code_Best_Practices

Regarding a recursive call, please provide me the example this will happen with the above code.