function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Christopher PezzaChristopher Pezza 

Trigger Update failing but saves

trigger LicenseUpdate on Customer_Health__c (after insert, after update) {
   Customer_Health__c NewLicenseNumber = new Customer_Health__c();
   sfLma__License__c SalesforceLicenses = new sfLma__License__c();

   Customer_Health__c updatech = trigger.new[0];

   NewLicenseNumber = [SELECT Used_Licenses__c, Licenses_Total__c FROM Customer_Health__c WHERE Id = :updatech.Id];
   SalesforceLicenses = [SELECT sfLma__Seats__c,sfLma__Used_Licenses__c,sfLma__Subscriber_Org_ID__c FROM sfLma__License__c WHERE 
                       sfLma__Subscriber_Org_ID__c LIKE :updatech.Org_ID__c AND sfLma__Package_Version__r.sfLma__Package__r.Name LIKE '%Bankr%'
                                                                    AND (sfLma__License__c.sfLma__License_Status__c LIKE '%Active%' OR sfLma__License__c.sfLma__License_Status__c LIKE '%Trial%')];

    system.debug('**' + NewLicenseNumber);

    system.debug('**' + SalesforceLicenses);
    
    NewLicenseNumber.Used_Licenses__c = SalesforceLicenses.sfLma__Used_Licenses__c;
    NewLicenseNumber.Licenses_Total__c = SalesforceLicenses.sfLma__Seats__c;

system.debug('**' + NewLicenseNumber);
    
    update(NewLicenseNumber);
}

I'm trying to update a field on a custom object when the record is updated that fills out the two fields debicted above but i get these errors when i try before update/insert and after update/insert

ERROR FOR BEFORE INSERT/UPDATE:
Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger LicenseUpdate caused an unexpected exception, contact your administrator: LicenseUpdate: execution of BeforeUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id a8Qa0000000CaRbEAK; first error: SELF_REFERENCE_FROM_TRIGGER, Object (id = a8Qa0000000CaRb) is currently in trigger LicenseUpdate, therefore it cannot recursively update itself: []: Trigger.LicenseUpdate: line 21, column 1

ERROR FOR AFTER INSERT/UPDATE:
Error:Apex trigger LicenseUpdate caused an unexpected exception, contact your administrator: LicenseUpdate: execution of AfterUpdate caused by: System.DmlException: Upsert failed. First exception on row 0 with id a8Qa0000000CaRbEAK; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, LicenseUpdate: maximum trigger depth exceeded Customer_Health trigger event AfterUpdate for [a8Qa0000000CaRb] Customer_Health trigger event AfterUpdate for [a8Qa0000000CaRb] Customer_Health trigger event AfterUpdate for [a8Qa0000000CaRb] Customer_Health trigger event AfterUpdate for [a8Qa0000000CaRb] Customer_Health trigger event AfterUpdate for [a8Qa0000000CaRb] Customer_Health trigger event AfterUpdate for [a8Qa0000000CaRb] Customer_Health trigger event AfterUpdate for [a8Qa0000000CaRb] Customer_Health trigger event AfterUpdate for [a8Qa0000000CaRb] Customer_Health trigger event AfterUpdate for [a8Qa0000000CaRb] Customer_Health trigger event AfterUpdate for [a8Qa0000000CaRb] Customer_Health trigger event AfterUpdate for [a8Qa0000000CaRb] Customer_Health trigger event AfterUpdate for [a8Qa0000000CaRb] Customer_Health trigger event AfterUpdate for [a8Qa0000000CaRb] Customer_Health trigger event AfterUpdate for [a8Qa0000000CaRb] Customer_Health trigger event AfterUpdate for [a8Qa0000000CaRb] Customer_Health trigger event AfterUpdate for [a8Qa0000000CaRb]: []: Trigger.LicenseUpdate: line 21, column 1

What am i doing wrong???
Best Answer chosen by Christopher Pezza
logontokartiklogontokartik
Can you try the below, before triggers does not need an explicit update

trigger LicenseUpdate on Customer_Health__c (before insert, before update) {
   Set<String> orgIds = new Set<String>(); // Set to store the Org IDs.
// Map to store LMA_License__c with key as org Ids
   Map<String,sfLma__License__c> sfLMAMap =  new Map<String,sfLma__License__c>(); 
   
   // Get the org Ids set 
   for(Customer_Health__c ch : Trigger.new){
      orgIds.add(ch.Org_ID__c);
   } 

  // Get the LMA_License and populate the map first
  for(sfLma__License__c sl : [SELECT sfLma__Seats__c,sfLma__Used_Licenses__c,sfLma__Subscriber_Org_ID__c FROM sfLma__License__c WHERE sfLma__Subscriber_Org_ID__c IN :orgIds AND sfLma__Package_Version__r.sfLma__Package__r.Name LIKE '%Bankr%' AND (sfLma__License__c.sfLma__License_Status__c LIKE '%Active%' OR sfLma__License__c.sfLma__License_Status__c LIKE '%Trial%')]{
     sfLMAMap.put(sl.sfLma__Subscriber_Org_ID__c,sl);
 }
 
 //After the map is populated, check to see if the org id.
 
 // 
 for(Customer_Health__c ch : Trigger.new){
       if(sfLMAMap.containsKey(ch.Org_ID__c)){
           ch.Used_Licenses__c  = sfLMAMap.get(ch.Org_ID__c).sfLma__Used_Licenses__c;
           ch.Licenses_Total__c = sfLMAMap.get(ch.Org_ID__c).sfLma__Seats__c;
      }else{
          ch.addError('Enter any error - license error'); // Add Error if org id is not found.
      }      
 }
    
}


All Answers

logontokartiklogontokartik
Your trigger doesnt seem to be right, few points, 

1. Your trigger is not built as per Bulk Design Pattern (it always considers only one record is inserted or updated)
2. You have writtern an update statement on the same object in the trigger (Line 21). It will cause recursion as the trigger gets fired again.
3. When you are in a before trigger, you dont have to write SOQL to refer the fields on the record. and cannot write an update statement for the same object. 
4. Not sure why you have NewLincenseNumber.

Can you briefly explain what you want to achieve via this trigger?



Christopher PezzaChristopher Pezza
I want to update two fields on the customer health every time it is edited with number of licenses used and total from the licenses object which i can't be achieved buy using a formula. I also want to catch that if there is no license record it doesn't fail and won't let you save a new record 
logontokartiklogontokartik
Can you try the below, before triggers does not need an explicit update

trigger LicenseUpdate on Customer_Health__c (before insert, before update) {
   Set<String> orgIds = new Set<String>(); // Set to store the Org IDs.
// Map to store LMA_License__c with key as org Ids
   Map<String,sfLma__License__c> sfLMAMap =  new Map<String,sfLma__License__c>(); 
   
   // Get the org Ids set 
   for(Customer_Health__c ch : Trigger.new){
      orgIds.add(ch.Org_ID__c);
   } 

  // Get the LMA_License and populate the map first
  for(sfLma__License__c sl : [SELECT sfLma__Seats__c,sfLma__Used_Licenses__c,sfLma__Subscriber_Org_ID__c FROM sfLma__License__c WHERE sfLma__Subscriber_Org_ID__c IN :orgIds AND sfLma__Package_Version__r.sfLma__Package__r.Name LIKE '%Bankr%' AND (sfLma__License__c.sfLma__License_Status__c LIKE '%Active%' OR sfLma__License__c.sfLma__License_Status__c LIKE '%Trial%')]{
     sfLMAMap.put(sl.sfLma__Subscriber_Org_ID__c,sl);
 }
 
 //After the map is populated, check to see if the org id.
 
 // 
 for(Customer_Health__c ch : Trigger.new){
       if(sfLMAMap.containsKey(ch.Org_ID__c)){
           ch.Used_Licenses__c  = sfLMAMap.get(ch.Org_ID__c).sfLma__Used_Licenses__c;
           ch.Licenses_Total__c = sfLMAMap.get(ch.Org_ID__c).sfLma__Seats__c;
      }else{
          ch.addError('Enter any error - license error'); // Add Error if org id is not found.
      }      
 }
    
}


This was selected as the best answer
Christopher PezzaChristopher Pezza
It works thanks i haven't done maps before so this is sweet what would the test coverage look like for one of these?