In case that you need to clone multiple childrens for one object this code may be usefull.

    Id orginalAccountId = // Here put Id of parent object.
    
    try {
        System.Savepoint initialState = Database.setSavepoint(); // Save database current state.

        // Clone Account (parent)
        queryString =  getQueryStringForAllEditableFields('Account', null);
        queryString += ' WHERE Id = \'' + orginalAccountId + '\'';
        Account accountToClone = Database.query(queryString);
        Account clonedAccount = accountToClone.clone(false,true,false,false);
        insert clonedAccount;
       
        // Clone all Account's contacts
        List<Contact> contactsToClone = new List<Contact>();
        List<Contact> clonedContacts = new List<Contact>();

        queryString =  getQueryStringForAllEditableFields('Contact');
        queryString += ' WHERE Account = \'' + orginalAccountId + '\'';
        contactsToClone = Database.query(queryString); //Return a list of all childes for original Account
        clonedContacts = contactsToClone.deepClone(false); // Clone whole list
        for (Contact ct : clonedContacts) {
            ct.Account = clonedAccount.Id; Replace parent Id with new Id of cloned Account.
        }
       
        PageReference pref = new PageReference('/'+ clonedAccount.Id); // Redirect to new account page.
        pref.setRedirect(true);
        return pref;
       
    } catch (DMLException ex){
        Database.rollback(initialState); // Rollback changes to avoid partial clone (if you have more types of children objects)
        account.addError('Account clone error! Details: '+ ex.getMessage());
        return null;
    }
    
    private String getQueryStringForAllEditableFields (String objectName, List<String> additionalFields) {
        String queryString = 'SELECT ';
        Map<String, Schema.SObjectField> objectFields = Schema.GetGlobalDescribe().get(objectName).getDescribe().fields.getMap();
       
        for (Schema.SObjectField field : objectFields.values()) {
            if (field.getDescribe().isCreateable()){
                queryString += field.getDescribe().getName().trim() + ', ';
            }
        }

        if (additionalFields != null && additionalFields.size() > 0) {
            for (String addField : additionalFields) {
                queryString += addField + ', ';
            }
        }

        queryString = queryString.removeEnd(', ');
        queryString += ' FROM ' + objectName;

        return queryString;
    }

 

   
© Paweł Woźniak