When you clone an sObject in Apex, it copies all the fields populated in that Apex object, not necessarily all fields on the record. Let’s say you have a Lead with FirstName, LastName, Company, LeadSource and Status populated. If you do the following, the clone will not have LeadSource and Status cloned from the original record. It will use the default values for Leads. That is because those fields were not queried into the object.

/* query lead and then clone it */
lead l = [select id, firstname, lastname, company from lead where id = '00Q3000000aKwVN' limit 1][0];
lead l2 = l.clone(false, true);
insert l2;

If you are cloning records, it can be frustrating to keep it updated as you add new fields to Salesforce. I generally want all new fields to be cloned too. I’ll code to any exceptions if needed. To help with this, I wrote myself a handy method to build me a SOQL statement and obtain all the writable fields.

So if I want to clone the Lead I describe above, I’d do the following and this will ensure that I will clone all the fields on the Lead. Since the method only adds Creatable fields to the SOQL, I don’t have to worry about trying to set a formula field or system field and generating an error.