I have created a apex class to clone a record with its related list. The record is cloned with related list but I am facing some issue. Those are:

1)after the click of clone button the record is cloned but it shouldn't save in the case of clicking "cancel" button.

2)the "save" button and "save & new" is working fine. I am facing problem with the cancel button. Please help me out. Thanks in advance!!

Apex class:

public with sharing class  Rfleet_Opportunity_Clone_With_Att {
    public ApexPages.StandardController controller {get;set;}
    public Opportunity opp {get;set;}
    public ID newRecordId {get;set;}
    public  Rfleet_Opportunity_Clone_With_Att(ApexPages.StandardController controller) {
    this.controller = controller;
    opp = (Opportunity) controller.getRecord();
    public pagereference cloneWithItems() {
       // Savepoint sp = Database.setSavepoint(); // setup the save point for rollback
        Opportunity newOpp;
        try {
            opp = [SELECT CurrencyIsoCode, Name, stagename,CloseDate FROM Opportunity where id = : opp.id];
            newOpp = opp.clone(false,true);
            insert newOpp;
            newRecordId = newOpp.id;

            // set the id of the new po created for testing
            // copy over the line items - ONLY INCLUDE THE FIELDS YOU WANT TO CLONE
           List < Opportunity_car_set__c > ListOpportunityCarSetUpdate = new List < Opportunity_car_set__c > ();
           List < Opportunity_car_set__c > ListOpportunityCarSet = [SELECT id,CurrencyIsoCode, Name, Opportunity__c, Quantity__c FROM Opportunity_car_set__c where Opportunity__c =: opp.id];
            for (Opportunity_car_set__c oppCarSet: ListOpportunityCarSet ) {

                Opportunity_car_set__c newOpportunityCarSet = oppCarSet.clone(false,true);
                newOpportunityCarSet.Opportunity__c = newOpp.id;
            insert ListOpportunityCarSetUpdate ;
                List<Attachment> ListAttachUpdate= new List<Attachment>();
            List<Attachment> ListAttach =[SELECT name,body FROM Attachment WHERE ParentID =: opp.id];
            for(Attachment att: ListAttach){
            Attachment newAttach= att.Clone(false,true);
            insert ListAttachUpdate;

            List<Note> ListNoteUpdate= new List<Note>();
            List<Note> ListNote =[SELECT Title,body FROM Note WHERE ParentID =: opp.id];
            for(Note att: ListNote){
            Note newNote= att.Clone(false,true);
            insert ListNoteUpdate;

        catch (Exception e) {

       return new PageReference('/' +newRecordId  + '/e?retURL=%2F' + newRecordId );



VF page:

<apex:page standardController="Opportunity" extensions="Rfleet_Opportunity_Clone_With_Att" action="{!cloneWithItems}">
     <apex:pageMessages />

  • share your complet page code. – Tushar Sharma Feb 2 '16 at 5:58
  • This the full code .adding this page in "buttons and links" for a specific button which is used to clone the record – uma451 Feb 2 '16 at 6:06
  • what action did you perform on cancel button? – Tushar Sharma Feb 2 '16 at 6:11
  • return new PageReference('/' +newRecordId + '/e?retURL=%2F' + newRecordId ); I USED THIS.So whatever the button it goes to the newly created record id – uma451 Feb 2 '16 at 6:31
  • instead of new record Id pass old record Id. – Tushar Sharma Feb 2 '16 at 6:34

I think the problem is you've immediately inserted the cloned opportunity and the related child records before you open the edit (/e) view of it. So cancelling at that point would only not commit any changes you made in that edited session - the original cloned values are already locked in.

You can specify a cancelURL (http://raydehler.com/cloud/clod/salesforce-url-hacking-basics-with-returl-saveurl-and-cancelurl.html) in your page reference to redirect to on cancel. If you point the cancelURL to a Visualforce page, then you can use code within that page to delete the cloned opportunity and related records.

| improve this answer | |

Ideally, your clone button would mimic the functionality of the built in clone button. Rather then acting as a pass through that clones immediately, you would create a Visualforce page that mimicked the page layout of the edit page.


On page load you would clone everything and store it in memory but not commit it to the database.

Page Content

This page would have clone/cancel buttons and the cancel button would do nothing but return the user to the original record. The clone button would commit the changes.

You would use field sets to determine which fields are displayed/required and where the appear.

You would then create some mechanism on the page for the related list such as a table with input fields so users could update the related items (we did this with quotes/quote line items so users could do things such as apply uplifts for renewals). What this looks like is up to you. At minimum, there should be a message explaining to the user that child records are going to be cloned as well.

Since the page clones an existing record most of the field values should already be filled out meaning if they just click clone again they get an exact copy, otherwise, they can update the record and related records prior to clicking clone.


This solves your problem with your cancel button as nothing is commited to the database when they cancel AND adds extra, valuable, features to your page.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.