0

I have two upsert statements which insert/update a parent and the child records. The parent may be a new record (created from an overridden "new" visualforce page) or an existing record (overridden "edit" visualforce page, same page). The problem I'm running into is that for a new record, after I upsert the parent it gets a new ID (as it should) but then if the upsert of the children fail (because it triggers validation rule) the parent still has the ID, even when I roll back with a savepoint. Then when I clear out the errors, the upsert of the parent fails because it still has the ID from the first failed upsert which is no longer valid.

How can I clear that ID if the upserts fail so that the database will give the parent a new id after a successful upsert?

My controller (the issues comes on the Save_PA method):

public with sharing class PayrollAuthorization_extn {

public list <PA_Distribution__c> PayrollDistributionList {get; set;}
public Payroll_Authorization__c PA;
public String rowID {get;set;}
public List<PA_Distribution__c> delProgramList {get; set;}
public ID TempPA_ID;

public PayrollAuthorization_extn(ApexPages.StandardController controller) {

PA = (Payroll_Authorization__c)controller.getRecord();
If (PA == null) PA = new Payroll_Authorization__c();
    PayrollDistributionList = [Select Id, Name, Program__c,Payroll_Authorization__c, Program_Percent__c, Program_as_Number__c,  Program_ID__c
        From PA_Distribution__c 
        Where Payroll_Authorization__r.id =: controller.getId()
        ];  
delProgramList = new List<PA_Distribution__c>();            
}

public void addRow(){
    PayrollDistributionList.add(new PA_Distribution__c( Payroll_Authorization__c = PA.id));
}

public PageReference SavePA (){
   Savepoint sp;  
    Try{
    sp = Database.setSavepoint();
    TempPA_ID = PA.id;
    upsert PA;
    for (PA_Distribution__c PD: PayrollDistributionList) {
        If (PD.Payroll_Authorization__c == null){
            PD.Payroll_Authorization__c = PA.Id;
            System.debug(PD);
        }
      }
    //System.debug ('PA_fromController following upsert ID is' + PA_fromController.id);

   upsert PayrollDistributionList;
   delete delProgramList;

    return (new ApexPages.StandardController(PA)).view();
    }
    Catch (Exception ex){
        Database.rollback(sp);
        PA.id = TempPA_ID;
        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR,ex.getMessage()));
    }
    return null;
}

public void deleteRow(){

    PA_Distribution__c del;

    Integer i = Integer.valueOf(ApexPages.currentPage().getParameters().get('RowID'));
        del= PayrollDistributionList[i];
        If (rowID != ''){    
          PayrollDistributionList.remove(i);
               If(del.Id <> null) delProgramList.add(del);

    }
   }

}

1 Answer 1

1

You could create a duplicate of what you are about to upsert, using the method deepClone(true) for your list and the clone(true) for your sObject. and after success... assign them to the original if needed.

Like...

public PageReference SavePA (){
    Savepoint sp;
    try{
        sp = Database.setSavepoint();
        Payroll_Authorization__c clonePA = PA.clone(true);
        List<PA_Distribution__c> clonePayrollDistributionList = PayrollDistributionList.deepClone(true);
        upsert clonePA;
        for (PA_Distribution__c PD: clonePayrollDistributionList) {
            If (PD.Payroll_Authorization__c == null){
                PD.Payroll_Authorization__c = clonePA.Id;
                System.debug(PD);
            }
        }
        //System.debug ('PA_fromController following upsert ID is' + PA_fromController.id);

        upsert clonePayrollDistributionList;
        delete delProgramList;


        // assign to the originals
        PA = clonePA;
        PayrollDistributionList = clonePayrollDistributionList;
        return (new ApexPages.StandardController(PA)).view();
    }
    catch (Exception ex){
        Database.rollback(sp);
        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR,ex.getMessage()));
    }
    return null;
}

You must log in to answer this question.

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