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
Anthony Zirilli 10Anthony Zirilli 10 

Bulking Code

Hi there, 

I've been trying to create line items on a parent object after the parent obect is created or edited. I got this far with the code and it works great. The only problem is that when using data loader to insert records it throws out this erros: "Too many SOQL queries: 101 Status code: 16" . How would I bulkify this code to make it work with large uploads? 

Additional details. The code runs so that the roll up field "Total Number of Line Items" equals "Copy Count" as shown below. Thanks in advance! 
-Anthony
User-added image

trigger CreatePrintCopyLineItem on Print_Copy__c (after insert,after update) {

    List <Print_Copy_Line_Item__c> LineItemToInsert = new List <Print_Copy_Line_Item__c> ();
    
    for (Print_Copy__c PrintCopy : Trigger.new) {

        if(PrintCopy.Copy_Count__c > PrintCopy.Total_Number_of_Line_Items__c) {
            Decimal count = PrintCopy.Copy_Count__c - PrintCopy.Total_Number_of_Line_Items__c;

            for(integer i=0;i < count; i++)
            {
                Print_Copy_Line_Item__c LineItemToAdd = new Print_Copy_Line_Item__c ();
                LineItemToAdd.Print_Copy__c=PrintCopy.Id;
                LineItemToInsert.add(LineItemToAdd);
            }
         }      
    }
    
    if(LineItemToInsert.size() > 0)
        insert LineItemToInsert;
Best Answer chosen by Anthony Zirilli 10
Amit Chaudhary 8Amit Chaudhary 8
Strange :( .
It look like your trigger is becoming recursive.

Please create below class first :-
public class TriggerHandler
{
     public static Boolean isFirstTime = true;
}

Then please update your trigger code like below code:-
trigger CreatePrintCopyLineItem on Print_Copy__c (after insert,after update) 
{

    List <Print_Copy_Line_Item__c> LineItemToInsert = new List <Print_Copy_Line_Item__c> ();
    if(TriggerHandler.isFirstTime)
    {
		TriggerHandler.isFirstTime = false;
		
		for (Print_Copy__c PrintCopy : Trigger.new) 
		{
			if(PrintCopy.Copy_Count__c > PrintCopy.Total_Number_of_Line_Items__c) 
			{
				Decimal count = PrintCopy.Copy_Count__c - PrintCopy.Total_Number_of_Line_Items__c;

				for(integer i=0;i < count; i++)
				{
					Print_Copy_Line_Item__c LineItemToAdd = new Print_Copy_Line_Item__c ();
					LineItemToAdd.Print_Copy__c=PrintCopy.Id;
					LineItemToInsert.add(LineItemToAdd);
				}
			}      
		}
		
		if(LineItemToInsert.size() > 0)
		{
			insert LineItemToInsert;
		}
	}	
}

Please check below for same issue:-
http://amitsalesforce.blogspot.in/2015/03/how-to-stop-recursive-trigger-in.html

Please let us know if this will help you.

Thanks,
Amit Chaudhar
amit.salesforce21@gmail.com

All Answers

Amit Chaudhary 8Amit Chaudhary 8
Hi  Anthony Zirilli 10,

Your below code is fine and even you are not doing soql in below trigger.
trigger CreatePrintCopyLineItem on Print_Copy__c (after insert,after update) 
{

    List <Print_Copy_Line_Item__c> LineItemToInsert = new List <Print_Copy_Line_Item__c> ();
    
    for (Print_Copy__c PrintCopy : Trigger.new) 
	{
        if(PrintCopy.Copy_Count__c > PrintCopy.Total_Number_of_Line_Items__c) 
		{
            Decimal count = PrintCopy.Copy_Count__c - PrintCopy.Total_Number_of_Line_Items__c;

            for(integer i=0;i < count; i++)
            {
                Print_Copy_Line_Item__c LineItemToAdd = new Print_Copy_Line_Item__c ();
                LineItemToAdd.Print_Copy__c=PrintCopy.Id;
                LineItemToInsert.add(LineItemToAdd);
            }
        }      
    }
    
    if(LineItemToInsert.size() > 0)
	{
        insert LineItemToInsert;
	}
}

Can you please chare all Print_Copy__c and "Print_Copy_Line_Item__c" trigger code.

If possible then please follow the below blog trigger best practice and trigger framework.
Always try to create single trigger per object
http://amitsalesforce.blogspot.in/2015/06/trigger-best-practices-sample-trigger.html

Please let us know if this will help you.

Thanks,
Amit Chaudhary
 
Anthony Zirilli 10Anthony Zirilli 10
This is the only trigger on this object and here is the error message after trying to create 500 records:
CreatePrintCopyLineItem: System.LimitException: Too many SOQL queries: 101 Status code: 16"
 
Anthony Zirilli 10Anthony Zirilli 10
No there is not
Amit Chaudhary 8Amit Chaudhary 8
Strange :( .
It look like your trigger is becoming recursive.

Please create below class first :-
public class TriggerHandler
{
     public static Boolean isFirstTime = true;
}

Then please update your trigger code like below code:-
trigger CreatePrintCopyLineItem on Print_Copy__c (after insert,after update) 
{

    List <Print_Copy_Line_Item__c> LineItemToInsert = new List <Print_Copy_Line_Item__c> ();
    if(TriggerHandler.isFirstTime)
    {
		TriggerHandler.isFirstTime = false;
		
		for (Print_Copy__c PrintCopy : Trigger.new) 
		{
			if(PrintCopy.Copy_Count__c > PrintCopy.Total_Number_of_Line_Items__c) 
			{
				Decimal count = PrintCopy.Copy_Count__c - PrintCopy.Total_Number_of_Line_Items__c;

				for(integer i=0;i < count; i++)
				{
					Print_Copy_Line_Item__c LineItemToAdd = new Print_Copy_Line_Item__c ();
					LineItemToAdd.Print_Copy__c=PrintCopy.Id;
					LineItemToInsert.add(LineItemToAdd);
				}
			}      
		}
		
		if(LineItemToInsert.size() > 0)
		{
			insert LineItemToInsert;
		}
	}	
}

Please check below for same issue:-
http://amitsalesforce.blogspot.in/2015/03/how-to-stop-recursive-trigger-in.html

Please let us know if this will help you.

Thanks,
Amit Chaudhar
amit.salesforce21@gmail.com
This was selected as the best answer
Anthony Zirilli 10Anthony Zirilli 10

That worked great! My only issue now is how to delete line items when copy count < total number of line items. I wrote this code, but it breaks under mass uploads: 

trigger DeletePrintCopyLineItem on Print_Copy__c (after update,after delete) {
    List<Id>LstID=new List<ID>();
    for(Print_Copy__c PrintCopy : Trigger.old){
    List<Print_Copy_Line_Item__c> existinglineitems = [Select Id from Print_Copy_Line_Item__c Where Print_Copy__r.Delete_Line_Items__c=True];
    delete existinglineitems;
    }
    }

Also I know it is best practice to have one trigger on each object. How do I combine this with the the updated trigger above to accomplish this? It should only run after update, not after insert like the above code.