I have a OWD, Case is Private and Payment1 and Payment2 has lookup relationship with the Case object. OWD for Payment1 and Payment2 also Private.

When Case is submitted by User i.e Original requestor, he should get READ only access on the Case and Payment1 and Payment2 object. Once case is Submitted, we need to make a Queue as the owner of the Case and Payment1 and Payment2.

Case is a single form which has Payment1 and Case fields. When Case is created then Case record will insert first then Payment1.

When Payment1 record inserted, I need make Payment1 owner same like Case Owner and I need to give READ access to Original requestor.

I did like below, but I get the below error.

10:51:49.14 (1226996739)|EXCEPTION_THROWN|[60]|System.FinalException: Record is read-only 10:51:49.14 (1227129014)|FATAL_ERROR|System.FinalException: Record is read-only

Here is the code

if(Trigger.isBefore && (Trigger.isInsert || Trigger.isUpdate)){
    MakeOwnerDynamically.checkOwner(Trigger.new, Trigger.oldMap);

if(Trigger.isAfter && (Trigger.isInsert || Trigger.isUpdate)){
    MakeOwnerDynamically.changePayment1Owner(Trigger.new, Trigger.oldMap);

Here is the logic I implemented, but dont know when to create the Payment1_Share record

Here is the another code

public static void checkOwner(List<Payment1__c> newPayment1, Map<Id, Payment1__c> oldPayment1Map){  
    Set<Id> caseIdSet = new Set<Id>();
    for(Payment1__c pay1 : newPayment1){

    Map<Id,Case> caseMap = new Map<Id,Case>([SELECT Id,RecordType.DeveloperName,OwnerId,
                                            FROM Case 
                                            WHERE Id IN :caseIdSet]);

    changePayment1Owner(newPayment1, caseMap);
    System.debug('~~~~~~~~ NoOfExtenpay1onClass calling end ~~~~~~~~~');

public static void changePayment1Owner(List<Payment1__c> newPayment1, Map<Id,Case> caseMap){
    List<Payment1__c> pay1InfoToUpdateOwnerLst = new List<Payment1__c>();

    for(Payment1__c pay1 : newPayment1){
        System.debug('CASE_OWNERID : '+caseMap.get(pay1.Case__c).OwnerId + ', pay1_OWNERID : '+pay1.OwnerId);

        if(caseMap.get(pay1.Case__c).OwnerId != pay1.OwnerId){
            pay1.OwnerId = caseMap.get(pay1.Case__c).OwnerId;
    System.debug('FINAL_pay1_DETAILS :: '+pay1InfoToUpdateOwnerLst);       

My Payment1_Share logic

Payment1__Share pi1Share = new Payment1__Share();
pi1Share.ParentId = pi.Id;
pi1Share.RowCause = 'Manual';
pi1Share.AccessLevel = 'Read';
pi1Share.UserOrGroupId = pi.CreatedById;


  • I cant create Share record in Before Insert.
  • I cant create findout if the old owner and Owner of the Case is same or different in After triiger..

Any help ?

1 Answer 1


From the Apex Developer Guide on Triggers:

There are two types of triggers:

  • Before triggers are used to update or validate record values before they’re saved to the database.
  • After triggers are used to access field values that are set by the system (such as a record's Id or LastModifiedDate field), and to affect changes in other records, such as logging into an audit table or firing asynchronous events with a queue. The records that fire the after trigger are read-only.

When you call MakeOwnerDynamically.changePayment1Owner, you are updating record values before they are saved to the database. Move the functionality to your before trigger.

  • Right.. But in before trigger logic I wont be able to insert Payment1_Share..that should be developed in After update ? Please see updates above
    – Kanika
    Jan 30, 2018 at 19:35
  • 1
    Yes, creating other records should go in the after trigger.
    – Adrian Larson
    Jan 30, 2018 at 19:42
  • if(Trigger.isAfter && (Trigger.isInsert || Trigger.isUpdate)) - Will be fine ? But I dont see its calling my required method... But how can I find who was the original Requestor in isAfter?
    – Kanika
    Jan 30, 2018 at 19:51

You must log in to answer this question.

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