You need to sign in to do that
Don't have an account?
❤Code
Need help !!!Getting DML limit error in apex trigger
Hi All,
I have a batch class which runs to delete old records, which in turn triggers a trigger on before delete. Now when the trigger runs it hits dml limit as calling class dml statements is running inside loop.
Can anyone help how to resolve this issue.
Below is the class and trigger -
trigger OpportunityTrigger on X_Opportunity__c (before delete)
{
for (X_Opportunity__c o : Trigger.old)
{
OpportunityMethods.opportunityDeleted(o);
}
}
public class OpportunityMethods
{
public static void opportunityDeleted(X_Opportunity__c o)
{
deleteOpportunityAccounts(o);
deleteOpportunitySalesTeams(o);
deleteOpportunityLineItems(o);
}
private static void deleteOpportunityAccounts(X_Opportunity__c o)
{
List<X_Opportunity_Account__c> opportunityAccounts = getOpportunityAccounts(o);
delete opportunityAccounts;
}
private static void deleteOpportunitySalesTeams(X_Opportunity__c o)
{
List<X_Opportunity_Sales_Team__c> salesTeams = getOpportunitySalesTeams(o);
delete salesTeams;
}
private static void deleteOpportunityLineItems(X_Opportunity__c o)
{
List<X_Opportunity_Line_Item__c> opportunityLineItems = getOpportunityLineItems(o);
delete opportunityLineItems;
}
private static List<X_Opportunity_Account__c> getOpportunityAccounts(X_Opportunity__c o)
{
List<X_Opportunity_Account__c> opportunityAccounts =
[select Id, Account__c, Advertiser__c, Agency__c, Close_Date__c,
Opportunity__c, Stage__c, Total_Amount__c
from X_Opportunity_Account__c
where Opportunity__c = :o.Id];
return opportunityAccounts;
}
private static List<X_Opportunity_Sales_Team__c> getOpportunitySalesTeams(X_Opportunity__c o)
{
List<X_Opportunity_Sales_Team__c> salesTeams =
[select Id, Opportunity__c, Sales_Rep__c, Split_Percent__c, OwnerId
from X_Opportunity_Sales_Team__c
where Opportunity__c = :o.Id];
if (salesTeams == null || salesTeams.size() == 0)
{
salesTeams = new List<X_Opportunity_Sales_Team__c>();
X_Opportunity_Sales_Team__c ost = new X_Opportunity_Sales_Team__c();
ost.Opportunity__c = o.Id;
ost.Sales_Rep__c = o.OwnerId;
ost.OwnerId = o.OwnerId;
ost.Split_Percent__c = 100.00;
insert ost;
salesTeams.add(ost);
}
return salesTeams;
}
private static List<X_Opportunity_Line_Item__c> getOpportunityLineItems(X_Opportunity__c o)
{
List<X_Opportunity_Line_Item__c> opportunityLineItems =
[select Id, Opportunity__c, Product__c, Product_Amount__c, Sales_Rep__c, OwnerId
from X_Opportunity_Line_Item__c
where Opportunity__c = :o.Id];
return opportunityLineItems;
}
}
I have a batch class which runs to delete old records, which in turn triggers a trigger on before delete. Now when the trigger runs it hits dml limit as calling class dml statements is running inside loop.
Can anyone help how to resolve this issue.
Below is the class and trigger -
trigger OpportunityTrigger on X_Opportunity__c (before delete)
{
for (X_Opportunity__c o : Trigger.old)
{
OpportunityMethods.opportunityDeleted(o);
}
}
public class OpportunityMethods
{
public static void opportunityDeleted(X_Opportunity__c o)
{
deleteOpportunityAccounts(o);
deleteOpportunitySalesTeams(o);
deleteOpportunityLineItems(o);
}
private static void deleteOpportunityAccounts(X_Opportunity__c o)
{
List<X_Opportunity_Account__c> opportunityAccounts = getOpportunityAccounts(o);
delete opportunityAccounts;
}
private static void deleteOpportunitySalesTeams(X_Opportunity__c o)
{
List<X_Opportunity_Sales_Team__c> salesTeams = getOpportunitySalesTeams(o);
delete salesTeams;
}
private static void deleteOpportunityLineItems(X_Opportunity__c o)
{
List<X_Opportunity_Line_Item__c> opportunityLineItems = getOpportunityLineItems(o);
delete opportunityLineItems;
}
private static List<X_Opportunity_Account__c> getOpportunityAccounts(X_Opportunity__c o)
{
List<X_Opportunity_Account__c> opportunityAccounts =
[select Id, Account__c, Advertiser__c, Agency__c, Close_Date__c,
Opportunity__c, Stage__c, Total_Amount__c
from X_Opportunity_Account__c
where Opportunity__c = :o.Id];
return opportunityAccounts;
}
private static List<X_Opportunity_Sales_Team__c> getOpportunitySalesTeams(X_Opportunity__c o)
{
List<X_Opportunity_Sales_Team__c> salesTeams =
[select Id, Opportunity__c, Sales_Rep__c, Split_Percent__c, OwnerId
from X_Opportunity_Sales_Team__c
where Opportunity__c = :o.Id];
if (salesTeams == null || salesTeams.size() == 0)
{
salesTeams = new List<X_Opportunity_Sales_Team__c>();
X_Opportunity_Sales_Team__c ost = new X_Opportunity_Sales_Team__c();
ost.Opportunity__c = o.Id;
ost.Sales_Rep__c = o.OwnerId;
ost.OwnerId = o.OwnerId;
ost.Split_Percent__c = 100.00;
insert ost;
salesTeams.add(ost);
}
return salesTeams;
}
private static List<X_Opportunity_Line_Item__c> getOpportunityLineItems(X_Opportunity__c o)
{
List<X_Opportunity_Line_Item__c> opportunityLineItems =
[select Id, Opportunity__c, Product__c, Product_Amount__c, Sales_Rep__c, OwnerId
from X_Opportunity_Line_Item__c
where Opportunity__c = :o.Id];
return opportunityLineItems;
}
}
Hi, Try like the code above. Instead of processing records one by one collect all records in list and pass it to the class and process it. Then you will not get any error.
In your logic, you are processing records one by one. So if you try with 200 records, you will receive this error. Always collect all values in a list and process it. Hope this will help you. Thanks.
{
List<X_Opportunity__c> lstoppty=new list<X_Opportunity__c>();
set<id> setOpptyId=new set<id>();
for (X_Opportunity__c o : Trigger.old)
{
lstoppty.add(o);
setOpptyId.add(o.id);
OpportunityMethods.opportunityDeleted(setOpptyId);
}
}
public class OpportunityMethods
{
public static void opportunityDeleted(set<id> oset)
{
deleteOpportunityAccounts(oset);
deleteOpportunitySalesTeams(oset);
deleteOpportunityLineItems(oset);
}
private static void deleteOpportunityAccounts(set<id> oset)
{
List<X_Opportunity_Account__c> opportunityAccounts = getOpportunityAccounts(o);
delete opportunityAccounts;
}
private static void deleteOpportunitySalesTeams(set<id> oset)
{
List<X_Opportunity_Sales_Team__c> salesTeams = getOpportunitySalesTeams(o);
delete salesTeams;
}
private static void deleteOpportunityLineItems(set<id> oset)
{
List<X_Opportunity_Line_Item__c> opportunityLineItems = getOpportunityLineItems(o);
delete opportunityLineItems;
}
private static List<X_Opportunity_Account__c> getOpportunityAccounts(set<id> oset)
{
List<X_Opportunity_Account__c> opportunityAccounts =
[select Id, Account__c, Advertiser__c, Agency__c, Close_Date__c,
Opportunity__c, Stage__c, Total_Amount__c
from X_Opportunity_Account__c
where Opportunity__c in :oset];
return opportunityAccounts;
}
private static List<X_Opportunity_Sales_Team__c> getOpportunitySalesTeams(set<id> oset)
{
List<X_Opportunity_Sales_Team__c> salesTeams =
[select Id, Opportunity__c, Sales_Rep__c, Split_Percent__c, OwnerId
from X_Opportunity_Sales_Team__c
where Opportunity__c in :oset];
List<X_Opportunity_Sales_Team__c> salesTeams2 = new List<X_Opportunity_Sales_Team__c>();
if (salesTeams == null || salesTeams.size() == 0)
{
for(X_Opportunity_Sales_Team__c ot:salesTeams){
X_Opportunity_Sales_Team__c ost = new X_Opportunity_Sales_Team__c();
ost.Opportunity__c = ot.Id;
ost.Sales_Rep__c = ot.OwnerId;
ost.OwnerId = ot.OwnerId;
ost.Split_Percent__c = 100.00;
salesTeams2.add(ost);
}
}
insert salesTeams2;
return salesTeams;
}
private static List<X_Opportunity_Line_Item__c> getOpportunityLineItems(set<id> oset)
{
List<X_Opportunity_Line_Item__c> opportunityLineItems =
[select Id, Opportunity__c, Product__c, Product_Amount__c, Sales_Rep__c, OwnerId
from X_Opportunity_Line_Item__c
where Opportunity__c in :oset];
return opportunityLineItems;
}
}
I am getting the below error -
Error: Compile Error: Initial term of field expression must be a concrete SObject: List<Id> at line 50 column 38
Can u please check.
Regards
Can u plz check. It might hit DML limit as dml will be runnign inisde loop.
Regards
Hi, please try this one.