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
blntblnt 

Inserting cloned object

Hi,

I am trying to save a clone of some object in a trigger in certain cases. However, as sObject.clone() copies over the Id and the Id is a read only field I am unable to insert the cloned object. Can anyone help?

Thanks,


Bao-Long Nguyen-Trong

* Error Message when trying to insert cloned object:

Insert failed. First exception on row 0 with id xxxxx; first error: INVALID_FIELD_FOR_INSERT_UPDATE, cannot specify Id in an insert call: [Id]:
Trigger.OnProposalUpdate: line 14, column 5


* Error message when trying to null the Id before inserting:
Error: Compile Error: Field is not writeable: Proposal__c.Id at line 11 column 9

* Sample code:

trigger OnProposalUpdate on Proposal__c (before update) {
List clonedProposals = new List();
For (Proposal__c oldProposal : Trigger.old) {
Proposal__c clonedProposal = oldProposal.clone();
if (oldProposal.Version__c != null) {
clonedProposal.Version__c = oldProposal.Version__c + 1;
}
else {
clonedProposal.Version__c = 1;
}
oldProposal.Id = null;
clonedProposals.add(clonedProposal);
}
insert clonedProposals;
}
Best Answer chosen by Admin (Salesforce Developers) 
blntblnt
I found the answer and though I would share: sObject objects actually have an overloaded clone() method (compared to plain Apex objects) that take 2 arguments:
1. Boolean opt_preserve_id,
2. Boolean opt_IsDeepClone

From the Apex Language Reference:

The optional opt_preserve_id argument determines
whether the ID of the original object is preserved or
cleared in the duplicate.

The optional opt_IsDeepClone argument determines
whether the method creates a full copy of the sObject,
or just a reference:
• If set to true, the method creates a full copy of the
sObject. All fields on the sObject are duplicated in
memory, including relationship fields. Consequently,
if you make changes to a field on the cloned sObject,
the original sObject is not affected.
• If set to false, the method creates a reference to
the original sObject. Consequently, if you make
changes to a field on the cloned sObject, the original
sObject is also affected.

All Answers

mahesh.epmahesh.ep
the easiest way is to do

clonedProposal.field1 = oldProposal.field1;
clonedProposal.field2 = oldProposal.field2;

except id;
blntblnt
Thanks. However, I am trying to make thing code as generic as possible so that when an admin user adds or deletes a field the trigger code does not need to be updated.

Any idea on how to make that happen?

Thanks,


Bao-Long Nguyen-Trong
blntblnt
I found the answer and though I would share: sObject objects actually have an overloaded clone() method (compared to plain Apex objects) that take 2 arguments:
1. Boolean opt_preserve_id,
2. Boolean opt_IsDeepClone

From the Apex Language Reference:

The optional opt_preserve_id argument determines
whether the ID of the original object is preserved or
cleared in the duplicate.

The optional opt_IsDeepClone argument determines
whether the method creates a full copy of the sObject,
or just a reference:
• If set to true, the method creates a full copy of the
sObject. All fields on the sObject are duplicated in
memory, including relationship fields. Consequently,
if you make changes to a field on the cloned sObject,
the original sObject is not affected.
• If set to false, the method creates a reference to
the original sObject. Consequently, if you make
changes to a field on the cloned sObject, the original
sObject is also affected.
This was selected as the best answer