You need to sign in to do that
Don't have an account?

trigger read only errors
HI,
I have. a trigger which is working fine. But i want to update the record value of the object but getting "execution of AfterInsert caused by: System.FinalException: Record is read-only" error. After processing all the records i want to again update the same object record value. Can somebody help. Below is my code snippet. I have commented the code which is not working fine:
I have. a trigger which is working fine. But i want to update the record value of the object but getting "execution of AfterInsert caused by: System.FinalException: Record is read-only" error. After processing all the records i want to again update the same object record value. Can somebody help. Below is my code snippet. I have commented the code which is not working fine:
public class JobTriggerHandler { public void onAfterInsert(List<Job_Control__c> lstNewObjA) { Set<String> setUniqueId = new Set<String>(); Set<String> objAStatus = new Set<String>(); for(Job_Control__c objA : lstNewObjA) { if(String.isNotBlank(objA.Unique_Id__c ) && objA.Status__c == 'Under Processing') { setUniqueId.add(objA.Unique_Id__c ); // objA.Status__c = 'With CRM'; } } // if(lstNewObjA.size() > 0){ // update lstNewObjA; //} if(!setUniqueId.isEmpty()) { List<Staging_Course__c> lststag = new List<Staging_Course__c>(); List<Course__c> lstObjC = new List<Course__c >(); for(Staging_Course__c objB: [SELECT test_Field__c , test_field_1__c,name FROM Staging_Course__c WHERE Unique_Id__c IN: setUniqueId]) { lstObjC.add(new Course__c( test_Field__c = objB.test_Field__c, test_field_1__c = objB.test_field_1__c , name = objB.name )); objB.Status__c = 'Completed'; lststag.add(objB); } if(!lststag.isEmpty()) update lststag; if(!lstObjC.isEmpty()) insert lstObjC; /* for(Job_Control__c objAUpdated : lstNewObjA) { objAUpdated.Status__c = 'Completed'; } if(lstNewObjA.size() > 0){ update lstNewObjA; }*/ } } }
In the After dml you can't Edit the Trigger.New() Lists because the Trigger.New() list become readonly so that you recieved this Error.
To avoid this you to follow the below Options:
1, Change the DML to Before Events bacause only in the Before DML Events the Trigger.New() is Editable.
2. Use the SOQL to query the Triiger.New() records as like RAJ V suggestion.
3. And one more suggestion create the new List and initiate the Record against Trigger.New() below it will avoid extra SOQL.
public class JobTriggerHandler
{
public void onAfterInsert(List<Job_Control__c> lstNewObjA)
{
Set<String> setUniqueId = new Set<String>();
Set<String> objAStatus = new Set<String>();
List<Job_Control__c> LstJobtoUpdate = new List<Job_Control__c>();
for(Job_Control__c objA : lstNewObjA)
{
if(String.isNotBlank(objA.Unique_Id__c ) && objA.Status__c == 'Under Processing')
{
setUniqueId.add(objA.Unique_Id__c );
// objA.Status__c = 'With CRM';
}
}
// if(lstNewObjA.size() > 0){
// update lstNewObjA;
//}
if(!setUniqueId.isEmpty())
{
List<Staging_Course__c> lststag = new List<Staging_Course__c>();
List<Course__c> lstObjC = new List<Course__c >();
for(Staging_Course__c objB: [SELECT test_Field__c , test_field_1__c,name FROM Staging_Course__c WHERE Unique_Id__c IN: setUniqueId])
{
lstObjC.add(new Course__c( test_Field__c = objB.test_Field__c, test_field_1__c = objB.test_field_1__c , name = objB.name ));
objB.Status__c = 'Completed';
lststag.add(objB);
}
if(!lststag.isEmpty())
update lststag;
if(!lstObjC.isEmpty())
insert lstObjC;
for(Job_Control__c objAUpdated : lstNewObjA)
{
Job_Control__c j = new Job_Control__c(id = objAUpdated.Id);
j.Status__c = 'Completed';
LstJobtoUpdate.add(j);
}
if(LstJobtoUpdate.size() > 0){
update LstJobtoUpdate;
}
}
}
}
Can you please Let me know if it helps or not!!!
If it helps don't forget to mark this as a best answer!!!
Thanks,
Raj
All Answers
In the After dml you can't Edit the Trigger.New() Lists because the Trigger.New() list become readonly so that you recieved this Error.
To avoid this you to follow the below Options:
1, Change the DML to Before Events bacause only in the Before DML Events the Trigger.New() is Editable.
2. Use the SOQL to query the Triiger.New() records as like RAJ V suggestion.
3. And one more suggestion create the new List and initiate the Record against Trigger.New() below it will avoid extra SOQL.
public class JobTriggerHandler
{
public void onAfterInsert(List<Job_Control__c> lstNewObjA)
{
Set<String> setUniqueId = new Set<String>();
Set<String> objAStatus = new Set<String>();
List<Job_Control__c> LstJobtoUpdate = new List<Job_Control__c>();
for(Job_Control__c objA : lstNewObjA)
{
if(String.isNotBlank(objA.Unique_Id__c ) && objA.Status__c == 'Under Processing')
{
setUniqueId.add(objA.Unique_Id__c );
// objA.Status__c = 'With CRM';
}
}
// if(lstNewObjA.size() > 0){
// update lstNewObjA;
//}
if(!setUniqueId.isEmpty())
{
List<Staging_Course__c> lststag = new List<Staging_Course__c>();
List<Course__c> lstObjC = new List<Course__c >();
for(Staging_Course__c objB: [SELECT test_Field__c , test_field_1__c,name FROM Staging_Course__c WHERE Unique_Id__c IN: setUniqueId])
{
lstObjC.add(new Course__c( test_Field__c = objB.test_Field__c, test_field_1__c = objB.test_field_1__c , name = objB.name ));
objB.Status__c = 'Completed';
lststag.add(objB);
}
if(!lststag.isEmpty())
update lststag;
if(!lstObjC.isEmpty())
insert lstObjC;
for(Job_Control__c objAUpdated : lstNewObjA)
{
Job_Control__c j = new Job_Control__c(id = objAUpdated.Id);
j.Status__c = 'Completed';
LstJobtoUpdate.add(j);
}
if(LstJobtoUpdate.size() > 0){
update LstJobtoUpdate;
}
}
}
}
Can you please Let me know if it helps or not!!!
If it helps don't forget to mark this as a best answer!!!
Thanks,
Raj
Yes, working fine now. Thanks Maharajan and Raj. Both the approach works fine.