[SalesForce] List values getting overwritten by last add statement

I have an Apex helper class called by a trigger which is to setup Apex sharing for Customer Community Plus users by sharing to their GroupId.

The class loops through the custom object records to setup sharing using a List for the custom object share and adding to it each time the for loop executes, however it seems to end up with only the last set of values multiple times in the list which causes an exception when I try to insert the share records.

Trigger code

if(trigger.isBefore && trigger.isUpdate){
    WSC_SPID_Trigger_Methods.updatePidShare(trigger.New, trigger.OldMap);
}

Trigger Handler code

public static void updatePidShare(List<PID__c> changedPid, Map<Id,PID__c>oldPid){
         System.debug('Pids to change '+changedPid.size());
         List<PID__Share> pidShares = new List<PID__Share>();
         if(changedPid.size()>0&&changedPid!=Null){
            PID__Share retailerRecord = new PID__Share();
            //Need to compare if Retailer on PID changed
             for(PID__c workPid :changedPid){
                 if(workPid.Current_Retailer__c!=oldPid.get(workPid.Id).Current_Retailer__c
                   &&workPid.Initial_Share__c==true){
                     System.debug('Old and new retailer'+workpid.Current_Retailer__c+''+oldpid.get(workpid.id).Current_retailer__c);
                     Id AccountId = workPid.Current_Retailer__c;
                     List<UserRole> retailerRoles = [SELECT Id FROM UserRole WHERE PortalAccountId = :AccountId];
                     if(retailerRoles.size()>0){
                          Id RoleId = [SELECT Id FROM UserRole WHERE PortalAccountId = :AccountId AND PortalRole ='Worker' LIMIT 1].Id;
                          Id GroupId = [SELECT Id FROM Group WHERE RelatedId = :RoleId LIMIT 1].Id;
                          System.debug('PID, role and group Id '+workpid.Id+' '+RoleId+''+GroupId);
                          System.assert(GroupId!=Null);
                          retailerRecord.ParentId = workPid.Id;
                          retailerRecord.UserOrGroupId = GroupId;
                          retailerRecord.AccessLevel = 'Read';
                          retailerRecord.RowCause = Schema.PID__Share.RowCause.Access_SPID_Retailer__c;           
                          pidShares.add(retailerRecord);
                          System.debug('Share Record '+retailerRecord.ParentId+' '+retailerRecord.UserOrGroupId);

                     }                

                 }
                 else if(workPid.Initial_Share__c==false&&workPid.Current_Retailer__c!=Null){
                     System.debug('Old and new retailer'+workpid.Current_Retailer__c+''+oldpid.get(workpid.id).Current_retailer__c);
                     Id AccountId = workPid.Current_Retailer__c;
                     List<UserRole> retailerRoles = [SELECT Id FROM UserRole WHERE PortalAccountId = :AccountId];
                     if(retailerRoles.size()>0){
                          Id RoleId = [SELECT Id FROM UserRole WHERE PortalAccountId = :AccountId AND PortalRole ='Worker' LIMIT 1].Id;
                          Id GroupId = [SELECT Id FROM Group WHERE RelatedId = :RoleId LIMIT 1].Id;
                          System.debug('SPID, Role and group Id '+workPid.Id+' '+RoleId+''+GroupId);
                          System.assert(GroupId!=Null);
                          retailerRecord.ParentId = workPid.Id;
                          retailerRecord.UserOrGroupId = GroupId;
                          retailerRecord.AccessLevel = 'Read';
                          retailerRecord.RowCause = Schema.PID__Share.RowCause.Access_SPID_Retailer__c;           
                          pidShares.add(retailerRecord);
                          System.debug('Share Record '+retailerRecord.ParentId+' '+retailerRecord.UserOrGroupId);
                         }
                 }

             }
             //testing error - show all records to be inserted
             for(PID__Share p1 :pidshares){
                 System.debug('Share records'+p1.Id+' '+p1.ParentId+' '+P1.UserOrGroupId+' '+p1.AccessLevel+' '+p1.RowCause);
             }

            //insert new records
             if(pidShares.size()>0){
                  System.debug('No of rows to add'+pidShares.size());
                  Database.SaveResult[] pidSharesInsertResult = Database.insert(pidShares, false);
             }
         }
    }

Debug log

Debug log showing where overwritten data occurs

enter image description here

Best Answer

I have now found the answer with reference to this existing question.

The variable for the custom object share PID__Share needed to be moved to within the loop so that it would get recreated each time, so at the start of the for loop it how has the working record created.

 public static void updatePidShare(List<PID__c> changedPid, Map<Id,PID__c>oldPid){
     System.debug('Pids to change '+changedPid.size());
     List<PID__Share> pidShares = new List<PID__Share>();
     if(changedPid.size()>0&&changedPid!=Null){
     //Need to compare if Retailer on PID changed
         for(PID__c workPid :changedPid){

            //Creation of working record for the PID__Share moved into the for loop
             PID__Share retailerRecord = new PID__Share();
Related Topic