3

I am having a pagination through StandardSetController in which I need to be able to select multiple record by check-box(I used wrapper class).

But when I am clicking on Next button which calls the below method I get this error.

"Modified rows exist in the records collection!"

public void pnext(){
if(recList != null){
    tempmapofWRP = new Map<Id,boolean> ();
    List<PO_LineItem__c> tempUpdatePOLINE = new List<PO_LineItem__c>();
    for(wrapperRec wrp: recList){
        wrpMap.put(wrp.record.Id,wrp) ;
        tempmapofWRP.put(wrp.record.Id,wrp.check);
    }
    for(wrapperRec wrp:wrpMap.values()){
        tempUpdatePOLINE.add(wrp.record);
    }
    validationRec();
    //con.save();
    system.debug('***con before null*****'+con);
    system.debug('***con after null*****');
    system.debug('****tempUpdatePOLINE****'+tempUpdatePOLINE);
    con = null;
    con = new ApexPages.StandardSetController(tempUpdatePOLINE);
    con.setPageSize(10);
    system.debug('***con new bind*****'+con);
    system.debug('****before caon next*****');
    con.next();
    system.debug('***Next called ****');
    wrltemplist =  new List<wrapperRec>();
    system.debug('***before getrecordcall *****');
    wrltemplist  = getrecordList();
    for(wrapperRec wrp: wrltemplist ){
        if(wrpMap.containsKey(wrp.record.Id)){
            wrp.check=wrpMap.get(wrp.record.Id).check;
        }
    }
}
else{
    wrltemplist =  new List<wrapperRec>();
    wrltemplist  = getrecordList();
}
}  

what to do in this scenario(I also need to maintain the check-box count in my code so that is why I am using map and again binding the values to displaying list which is "wrltemplist")

EDIT Version with deep clone DIDN'T Worked:

    Public void pnext(){
   con.next();
} 

AND the controller deepclone code is:

Public List<wrapperRec> getrecordList() {
    List<wrapperRec>recListtemp = new List<wrapperRec>();
    recListtemp = recListtoReturn  ;
    recList = new List<wrapperRec>();
    system.debug('****recListtemp *****'+recListtemp );
    system.debug('***inside getrecordList****');
    try{
        if(con.getRecords() != null){
            system.debug('***con not null****');
            for (PO_LineItem__c poLineOb : (List<PO_LineItem__c>)con.getRecords().deepClone(true, true, true)){
                 system.debug('***inside of for loop to getRecords***');
                 wrapperRec rec = new wrapperRec(poLineOb ,false);
                 recList.add(rec);   
            } 
            if(recListtemp != null){
                system.debug('****recListtemp not null*****');
                for(wrapperRec wrp: recListtemp ){
                     wrpMap.put(wrp.record.Id,wrp) ;
                }
                system.debug('****wrpMap*****'+wrpMap.values());
                for(wrapperRec wrp: recList){
                    if(wrpMap.containsKey(wrp.record.Id)){
                        wrp.check=wrpMap.get(wrp.record.Id).check;
                        wrp.record = wrpMap.get(wrp.record.Id).record;
                    }
                }
                system.debug('****after second 2 wrap for loop*****');
             }
        }

        recListtoReturn  = recList ;
        system.debug('****recListtoReturn  *****'+recListtoReturn  );
        return recListtoReturn  ;
    }
    catch(Exception ex){
        ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'No Open OP Line Item Record for this Supplier'));
        return null;
    }
}

But this dont works. If i edit values on any page it run into above mentioned error .. What I am doing wrong!!

3
  • Which line produces the error?
    – Mike Chale
    Mar 26, 2013 at 16:34
  • @Mike Chale con.next();
    – user614946
    Mar 28, 2013 at 5:23
  • Apparently con.save() also resolves it, is there a benefit of cloning and manually updating using apex rather than using the standard set controller save ? Apr 19, 2013 at 13:37

2 Answers 2

7

This is a "safety" feature, in that it prevents you from accidentally losing changes to records in the standard set controller.

You can prevent these values from changing by avoiding making any updates to records retrieved from controller.getRecords() in apex and only using apex:outputfield in the visualforce page.

If the values need to change and you need to handle that you can avoid the safety feature by deep cloning the list so that the records you're working with and modifying those instead.

List<sObject> modifiable = controller.getRecords().deepClone(true, true, true);
1
  • Hi @Ralph It helped but for the first next button click but when I go to the third page (second time click on next button) I again run into the above error..
    – user614946
    Mar 28, 2013 at 5:23
3

Hi I figgured it out..

Feel free to use it if anyone is in need..

  1. Use the controller.getRecords().deepClone(true, true, true); to get the records cloned data.

    2.{If wrapper class is used} also clone the list on wrapper records that are bidden with the page. By doing this :

    List<Account> tempacc = new List<Account>();
        List<Account> tempaccsec = new List<Account>();
        for (WrapperAccount wrp: wrpRecordList){
            tempacc .add(wrp.accRecord);
        }
        tempaccsec = tempacc .deepclone(true,true,true);
        for(Account opline: tempaccsec ){
            WrapperAccount rec = new WrapperAccount (opline,wrpMap.get(opline.Id).accCheck);
            wrpRecordListDisplay.add(rec );
        }
    return wrpRecordListDisplay;
    

Mark as answer if this helps!!

1
  • 3
    Erm... I think it's up to you to select an answer as "accepted" because you asked the question :)
    – eyescream
    Mar 29, 2013 at 12:39

You must log in to answer this question.

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