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
Vegaln1Vegaln1 

Can't get a custom object field to be populated from a Map.

In order to avoid a DML governor limitiation,I'm trying to bulk update a custom object field using Maps. In the Debug log I see the values populating the field yet it is never 'updated' in the UI. I'm missing a step. The purpose of this trigger is when a Contracts__c.Status__c is set to 'Current', also set the associated entitlement records 'Entitlement_Status__c' record to the same value.

 

Thanks.

 

This is the trigger:

 

trigger ContractUpdateAEs on Contracts__c (after update)
{
    Integer i = 0;
    Map<ID,Contracts__c> conMap = new Map<ID,Contracts__c>(Trigger.old);
    Set<ID> conSet = conMap.keySet();    
    List<Contracts__c> conList  = [select Id, Status__c  from Contracts__c where Id IN :conSet];
      
    Map<String,Asset_Entitlement__c> aeMap = new Map<String,Asset_Entitlement__c> ([select Id, Entitlement_Status__c, Contracts_Status__c, Contracts__c from Asset_Entitlement__c where Contracts__c IN :conSet]);
    Set<String> aeSet = aeMap.keySet(); 
    Contracts__c old_c = Trigger.old[i]; //Contains image before change
    Contracts__c new_c = Trigger.new[i]; // Contains image of change to be committed
    if(old_c.Status__c != 'Current' && new_c.Status__c == 'Current')
    {      
          
      for(Asset_Entitlement__c aes :aeMap.Values())
      {
        aes.Entitlement_Status__c = aeMap.get(aes.Id).Contracts_Status__c;
        system.Debug('!!!!!!!!!:aes.Entitlement_Status__c  ' + aes.Entitlement_Status__c + '          AE Id is: ' + aes.Id);//These values look correct in debug log.   
      }     
 
    }
 
   
}

Best Answer chosen by Admin (Salesforce Developers) 
aalbertaalbert

Yeah, that is a different issue. You have to execute the update DML operation - otherwise the data is not posted back to the database to be committed. The issue of "too many dml rows" is a governor limit that is calculated in runtime and it depends on (a) how the apex is invoked (b) how many records initiated the apex transaction. In this case, it sounds like only 1 record caused the trigger to fire, therefore you can only perform a DML operation against 100 records. 

 

As for a solution, I recommend performing the update statement in a method annotated with the @future keyword.  This will execute the method asynchronously so your trigger will complete more efficiently. Additionally, you will get higher governor limits in the @future method and therefore be able to update the 133 records (1,000+ actually). 

 

 

All Answers

aalbertaalbert

I don't see the Update DML statement in your code. Where are you explicitly updating those records?

 

Vegaln1Vegaln1

 

 

Yes, I tried that. If I use a update then I recieve a DML error. I had thought I could use :

:

update aeMap.Values();

 

but I then get the 

 

Too many DML rows: 133:

 and the Nasty-Gram from  ApexApplication.

 

I tried using a List and Map combination and using a update List  but got he same results. Is there no way to get around this limitation? In the past I've used a trigger to call a @future APEX class  but I really thought bulk triggers using Maps would be be appropriate.

aalbertaalbert

Yeah, that is a different issue. You have to execute the update DML operation - otherwise the data is not posted back to the database to be committed. The issue of "too many dml rows" is a governor limit that is calculated in runtime and it depends on (a) how the apex is invoked (b) how many records initiated the apex transaction. In this case, it sounds like only 1 record caused the trigger to fire, therefore you can only perform a DML operation against 100 records. 

 

As for a solution, I recommend performing the update statement in a method annotated with the @future keyword.  This will execute the method asynchronously so your trigger will complete more efficiently. Additionally, you will get higher governor limits in the @future method and therefore be able to update the 133 records (1,000+ actually). 

 

 

This was selected as the best answer
Vegaln1Vegaln1

Hello  When you say

' As for a solution, I recommend performing the update statement in a method annotated with the @future keyword.

 

That is the same thing as I said previously by calling another APEX class right? Or, do yo mean I can use the @future in the exsting trigger. If this is the case I was unaware we could use it it a trigger. I thought it was only for a APEX class?

 

Regards,

aalbertaalbert

Sorry, I should have elaborated more. How many records are initiating the trigger in your test case? If 1, then you can only perform DML statements on 100 records. If 2, then you its 200. Its scale by the number of records the trigger is initiated with.

 

Secondly, with respect to @future, you are right. It has to be in a seperate Apex class which runs asynchronously. The trigger can not specify @future nor run asynchronously. 

 

 

Vegaln1Vegaln1

Hello. Thanks you for the updates. It is only 1 record that is calling the trigger so I understand the 100 record limit in this case. So, I will created a separate APEX class to perform the update. Once again, thank you for the responses. They were very helpful.

 

Regrds,