7

This trigger creates an entitlement for every account that meets certain criteria.

I have read the triggers process records in chunks of 200 but I am not understanding why the trigger below only creates 200 entitlements records even when I am inserting 250 accounts.

It seems like only the first chunk is processed by the trigger. I don't see any errors in the logs. Thanks in advance.

This is part of the code.

UPDATE:I have added the 2 lines of code at the beginning that are causing the issue.

 if(util1.accountEntitlementAssignment) return;
     util1.accountEntitlementAssignment=true;

for(Entitlement ent: [Select Id,AccountId from Entitlement Where Status='Active']){
    AccsWithEnt.add(ent.AccountId);
}


for (Account acc : trigger.new) {
    if(acc.test_Subscription_Type__c=='testEnterprise'){
        //Only create entitlements for accounts that don't have one
        if(!AccsWithEnt.contains(acc.id)){
            createentitlement.add(new Entitlement (
                Name='Enterprise Entitlement',
                AccountId=acc.Id,
                StartDate=todayDate,
                EndDate=todayDate.addYears(5),
                SlaProcessId=slaMap.get('Enterprise Entitlement').Id)); 
        }           
    }
}

Insert createentitlement;    

This is how I am testing it

List<Account> accs=new List<Account>();

for(Integer i=0;i<250;i++){

    accs.add(new Account(
        name='test'+i,
        test_Subscription_Type__c='testEnterprise'));           
    }   

    insert accs;
}
3
  • can you please specify the event your trigger is in?Before insert or after insert,etc.code looks ok to me Oct 10, 2013 at 15:39
  • Sure is after insert,after update
    – PepeFloyd
    Oct 10, 2013 at 15:40
  • try with small no of records like 199 and then 201 .Just playing around the code could give some clue Oct 10, 2013 at 15:42

1 Answer 1

11

Your trigger isn't bulk-safe, although that has little to do with the problem at hand. Your trigger should certainly create 250 brand new entitlements; I think you might be missing something. It's true that your trigger will be batched into sets of 200 (so, 200 on the first loop, plus 50 on the second), but all 250 entitlements should be created.

Make sure you're not just reading the logs wrong. You should query the entitlements back afterwards and assert that there are indeed 250 entitlements:

Entitlement[] entitlements = [SELECT Id FROM Entitlement WHERE AccountId IN :accs];
System.assertEquals(250, entitlements.size());

Here's a better way to approach your trigger:

Entitlement[] newEntitlements = new Entitlement[0];
Set<Id> newAcctIds = Trigger.newMap.keySet().clone();
for(Entitlement record:[SELECT AccountId FROM Entitlement WHERE Status='Active' AND AccountId IN :Trigger.new])
    newAcctIds.remove(record.AccountId);
for(Id recordId:newAcctIds)
    newEntitlements.add(
        new Entitlement(
            Name='Enterprise Entitlement', 
            AccountId=recordId, 
            StartDate=Date.Today(), 
            Date.Today().addYears(5), 
            SLAProcessId=slaMap.get('Enterprise Entitlement').Id));
insert newEntitlements;
4
  • Thanks very much for the suggested changes I have implemented them, and you are right, the real problem is not with the code I posted, I was ignoring the fact that I used this approach to avoid an infinite loop on that trigger raydehler.com/cloud/clod/… Do you know a better approach to that one so to avoid this type of issues?
    – PepeFloyd
    Oct 10, 2013 at 20:28
  • Infinite trigger recursion is usually handled through a static variable (as in the link), or through guarded mechanisms, such as what you're doing here. There's no problem with this design pattern; it's actually very common amongst developers.
    – sfdcfox
    Oct 10, 2013 at 20:53
  • I think I am seeing the problem described in the comments on that article.
    – PepeFloyd
    Oct 10, 2013 at 21:07
  • 2
    Actually, they're referring to the static variable problem. Doing a sanity check (e.g. don't create entitlements that already exist) is a far better solution, because it is agnostic of prior trigger runs from Apex Code batching.
    – sfdcfox
    Oct 10, 2013 at 21:33

You must log in to answer this question.

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