function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
App DevelopmentApp Development 

how to handle unique fields while cloning?

I have developed below code fro cloning but unfortunately because of unique field i am getting error of duplication.

here one text field set to unique.

Apex class: 

public class GSDPartnerCloneWithSkillsController {

    public ApexPages.StandardController controller {get; set;}
    public GSD_Partner__c GSDP {get;set;}
    public ID newRecordId {get;set;}
    public Id OldGSDResourceId {get;set;}
    public Id NewGSDResourceId {get;set;}

    
    public GSDPartnerCloneWithSkillsController(ApexPages.StandardController controller) {

        this.controller = controller;
        GSDP = (GSD_Partner__c)controller.getRecord();

    }
    
    public PageReference cloneWithItems() {

         Savepoint sp = Database.setSavepoint();
         GSD_Partner__c newGSDP;

         try {
         
             GSDP = (GSD_Partner__c) GSDDataUtility.getObject('GSD_Partner__c', GSDP.id);
             
             newGSDP = GSDP.clone(false);
             insert newGSDP;

            
             newRecordId = newGSDP.id;
           
           
             GSD_Resource__c OldGSDResource = [select id from  GSD_Resource__c where Partner__c = :GSDP.id limit 1];
             OldGSDResourceId = OldGSDResource.id;
             system.debug('OldGSDResourceId :'+OldGSDResourceId );
             
             GSD_Resource__c NewGSDResource = [select id from  GSD_Resource__c where Partner__c = :newRecordId  limit 1];
             NewGSDResourceId = NewGSDResource.id;
             system.debug('NewGSDResourceId :'+NewGSDResourceId);
             
             CLoneGSDResourceLang();
             CLoneGSDResourceNon();
             CLoneGSDResourcePPS();
             CLoneGSDResourcePMaster();
             CLoneGSDResourceServices();
             CLoneGSDResourceTech();

         } catch (Exception e){
            Database.rollback(sp);
            ApexPages.addMessages(e);
            return null;
         }

        return new PageReference('/'+newGSDP.id+'/e?retURL=%2F'+newGSDP.id);
    }
    
    public void CLoneGSDResourceLang(){
    
        List<GSD_Resource_Skills_mapping__c> InsertnewSkillList = new List<GSD_Resource_Skills_mapping__c>();
        List<GSD_Resource_Skills_mapping__c> SkillsList = [select id,Skill_Name__c,Skill_Category__c,Standard__c,Stand_By__c,Non_Product_Skill_Level__c,Web_App_Resp_Created_Dt__c,Web_App_Resp_Modified_Dt__c,Responsibility_Skill_Level__c,Web_App_Employee_Id__c,Web_App_ID__c,Web_App_Skill_Id__c from GSD_Resource_Skills_mapping__c where Skill_Category__c = :Label.GSDResourceLang and Resource_ID__c = :OldGSDResourceId];  
        if(!SkillsList.isEmpty()){
            for (GSD_Resource_Skills_mapping__c GSDrskill : SkillsList) {
                  GSD_Resource_Skills_mapping__c newGSDrskill  = GSDrskill.clone(false);
                  newGSDrskill.Resource_ID__c = NewGSDResourceId;
                  InsertnewSkillList.add(newGSDrskill);
            }
            system.debug('InsertnewSkillList:'+InsertnewSkillList);
            insert InsertnewSkillList ;
        }
    }
    
    public void CLoneGSDResourceNon(){
    
        List<GSD_Resource_Skills_mapping__c> InsertnewSkillList = new List<GSD_Resource_Skills_mapping__c>();
        List<GSD_Resource_Skills_mapping__c> SkillsList = [select id,Skill_Name__c,Skill_Category__c,Standard__c,Stand_By__c,Non_Product_Skill_Level__c,Web_App_Resp_Created_Dt__c,Web_App_Resp_Modified_Dt__c,Responsibility_Skill_Level__c,Web_App_Employee_Id__c,Web_App_ID__c,Web_App_Skill_Id__c from GSD_Resource_Skills_mapping__c where Skill_Category__c = :Label.GSDResourceNon and Resource_ID__c = :OldGSDResourceId];  
        if(!SkillsList.isEmpty()){
            for (GSD_Resource_Skills_mapping__c GSDrskill : SkillsList) {
                  GSD_Resource_Skills_mapping__c newGSDrskill  = GSDrskill.clone(false);
                  newGSDrskill.Resource_ID__c = NewGSDResourceId;
                  InsertnewSkillList.add(newGSDrskill);
            }
            system.debug('InsertnewSkillList:'+InsertnewSkillList);
            insert InsertnewSkillList ;
        }
    }
    
    public void CLoneGSDResourcePPS(){
    
        List<GSD_Resource_Skills_mapping__c> InsertnewSkillList = new List<GSD_Resource_Skills_mapping__c>();
        List<GSD_Resource_Skills_mapping__c> SkillsList = [select id,Skill_Name__c,Skill_Category__c,Standard__c,Stand_By__c,Non_Product_Skill_Level__c,Web_App_Resp_Created_Dt__c,Web_App_Resp_Modified_Dt__c,Responsibility_Skill_Level__c,Web_App_Employee_Id__c,Web_App_ID__c,Web_App_Skill_Id__c from GSD_Resource_Skills_mapping__c where Skill_Category__c = :Label.GSDResourcePPS and Resource_ID__c = :OldGSDResourceId];  
        if(!SkillsList.isEmpty()){
            for (GSD_Resource_Skills_mapping__c GSDrskill : SkillsList) {
                  GSD_Resource_Skills_mapping__c newGSDrskill  = GSDrskill.clone(false);
                  newGSDrskill.Resource_ID__c = NewGSDResourceId;
                  InsertnewSkillList.add(newGSDrskill);
            }
            system.debug('InsertnewSkillList:'+InsertnewSkillList);
            insert InsertnewSkillList ;
        }
    }
    
    public void CLoneGSDResourcePMaster(){
    
        List<GSD_Resource_Skills_mapping__c> InsertnewSkillList = new List<GSD_Resource_Skills_mapping__c>();
        List<GSD_Resource_Skills_mapping__c> SkillsList = [SELECT Id, Name, Skill_Name__r.Name, Responsibility_Skill_Level__c, Skill_Name__r.Product_Description__c, Skill_Name__r.Portfolio__c FROM GSD_Resource_Skills_mapping__c WHERE Resource_ID__c = :OldGSDResourceId AND Skill_Category__c =: Label.GSDResourcePMaster ];
        if(!SkillsList.isEmpty()){
            for (GSD_Resource_Skills_mapping__c GSDrskill : SkillsList) {
                  GSD_Resource_Skills_mapping__c newGSDrskill  = GSDrskill.clone(false);
                  newGSDrskill.Resource_ID__c = NewGSDResourceId;
                  InsertnewSkillList.add(newGSDrskill);
            }
            system.debug('InsertnewSkillList:'+InsertnewSkillList);
            insert InsertnewSkillList ;
        }
    }
    
    public void CLoneGSDResourceServices(){
    
        List<GSD_Resource_Skills_mapping__c> InsertnewSkillList = new List<GSD_Resource_Skills_mapping__c>();
        List<GSD_Resource_Skills_mapping__c> SkillsList = [SELECT Id, Name, Skill_Name__r.Name, Responsibility_Skill_Level__c, Skill_Name__r.Product_Description__c, Skill_Name__r.Portfolio__c, Skill_Name__r.Support_Activity__c,Standard__c, Stand_By__c FROM GSD_Resource_Skills_mapping__c WHERE Resource_ID__c = :OldGSDResourceId AND Skill_Category__c ='Services' ];
        if(!SkillsList.isEmpty()){
            for (GSD_Resource_Skills_mapping__c GSDrskill : SkillsList) {
                  GSD_Resource_Skills_mapping__c newGSDrskill  = GSDrskill.clone(false);
                  newGSDrskill.Resource_ID__c = NewGSDResourceId;
                  InsertnewSkillList.add(newGSDrskill);
            }
            system.debug('InsertnewSkillList:'+InsertnewSkillList);
            insert InsertnewSkillList ;
        }
    }
    
    public void CLoneGSDResourceTech(){
    
        List<GSD_Resource_Skills_mapping__c> InsertnewSkillList = new List<GSD_Resource_Skills_mapping__c>();
        List<GSD_Resource_Skills_mapping__c> SkillsList = [SELECT Id, Name, Responsibility_Skill_Level__c, Skill_Name__r.Name, Skill_Name__r.Technologies_Name__c FROM GSD_Resource_Skills_mapping__c WHERE Resource_ID__c =:OldGSDResourceId  AND Skill_Category__c =: Label.GSDResourceTech ];
        if(!SkillsList.isEmpty()){
            for (GSD_Resource_Skills_mapping__c GSDrskill : SkillsList) {
                  GSD_Resource_Skills_mapping__c newGSDrskill  = GSDrskill.clone(false);
                  newGSDrskill.Resource_ID__c = NewGSDResourceId;
                  InsertnewSkillList.add(newGSDrskill);
            }
            system.debug('InsertnewSkillList:'+InsertnewSkillList);
            insert InsertnewSkillList ;
        }
    }
}

apex class:

public class GSDDataUtility {
    public static sObject getObject(string objName, string id) {
 
        String fieldnames = '';
        sObject obj;
        try {
            Map < String, Schema.SObjectType > m = Schema.getGlobalDescribe();
            Schema.SObjectType s = m.get(objName);
            Schema.DescribeSObjectResult r = s.getDescribe();
 
        
            Map < String, Schema.SObjectField > fields = r.fields.getMap();
            for (string field: fields.keySet()) {
                if (fieldnames == '') {
                    fieldnames = field;
                } else {
                    fieldnames += ',' + field;
                }
            }
 
            
            String sql = 'SELECT ' + fieldnames + ' FROM ' + objName + ' WHERE Id=\'' + id + '\'';
            System.debug(sql);
            obj = database.query(sql);
 
        } catch (Exception e) {
            System.debug('get Fields Error' + e.getMessage());
            ApexPages.addMessages(e);
            return null;
        }
        return obj;
    }
}
JayantJayant
After cloning, explicitly set the appropriate value in unique field (on clone record) before DML.

 
App DevelopmentApp Development

List<GSD_Partner__c> InsertGSDPList = new List<GSD_Partner__c>();
             List<GSD_Partner__c> GSDPList = [SELECT supervisor__c,Queue_Suffix__c,case_exchange_identifier__c,quota_factor__c,minimum_assignments_monthly__c,open_all_hours__c,account__c,country_iso__c,notes__c,portfolio__c,maximum_assignments_daily__c,createdbyid,lastmodifieddate,id,phone__c,portal_user_identifier__c,last_daily_counter_reset__c,logistics_badge_id__c,name,isdeleted,queue__c,resource__c,systemmodstamp,provider_type__c,last_monthly_counter_reset__c,does_diagnosis__c,email__c,send_case_exchange_reminders__c,mru_code__c,createddate,can_see_quotes__c,ownerid,assignment_counter_daily__c,country_name__c,active__c,case_exchange_enabled__c,assignment_counter_monthly__c,does_own_logistics_and_parts__c,engagement_method__c,maximum_assignments_monthly__c,lastmodifiedbyid,currencyisocode,commitment_levels__c FROM GSD_Partner__c WHERE Id = :GSDP.id];
             for(GSD_Partner__c GSDP : GSDPList ){
                 newGSDP = GSDP.clone(false);
                 newGSDP.Queue_Suffix__c = 'Enter Unique value';
                 InsertGSDPList.add(newGSDP);
             } 
             insert InsertGSDPList;

yeh done this already..but still if u will not change the text value which we set as "Enter Unique value'" so it will again throw error of having duplicate record
 

JayantJayant
That's correct. If you see you are iterating over a collection here and setting the same value in unique field for all of them (collection members) which is fundamentally wrong. 
What's the purpose of this unique field ? It should be holding something meaningful in the context of your org  (which is expected to be unique) rather than some arbitrary string literal.
If you just want to add any arbitrary literal to avoid error, try this - 
Integer i = 0;
for(GSD_Partner__c GSDP : GSDPList ){
                 newGSDP = GSDP.clone(false);
                 newGSDP.Queue_Suffix__c =GSDP.Queue_Suffix__c + '_' + i;
                 InsertGSDPList.add(newGSDP);
                 i++;
             } 

You may still face errors  as everytime you are suffixing an expected numeral. Once it runs for a specifix record (with value xyz), database will already have xyz_1. Next time same record with value xyz is processed, you will run into error.

Probably, instead of a simple literal using a timestamp like below would be most full-proof - 

Integer i = 0;
for(GSD_Partner__c GSDP : GSDPList ){
                 newGSDP = GSDP.clone(false);
                 newGSDP.Queue_Suffix__c =GSDP.Queue_Suffix__c + '_' + System.currentTimeMillis() + '_' + i;
                 InsertGSDPList.add(newGSDP);
                 i++;
             } 
 
JayantJayant
If this is resolved, please do mark it as Resolved and select the most appropriate answer as the best answer.
App DevelopmentApp Development
do we have any other approach? can u suggest on anything else?
 
JayantJayant
You should find out why exactly the field has been marked as Unique and what's the value it expects ?
Ideally if its unique, there has to be some rule to determine the value it can accept (which will be naturally unique) and you should determine and set that value in your code.
Kenny Dick 7Kenny Dick 7
Hi Everyone, while searching for a solution to this issue some 5 years later :) we successfully used a Record Triggered Flow to remove the unique value before create. Perhaps people know this already but I thought I would share.
Sudheera LakmalSudheera Lakmal
Hello Kenny,
Could you please elaborate how did you remove the unique value before create by using Record Triggered Flow? Currently I'm stuck in the same issue. Thanks...!