+ Start a Discussion

Problem inserting after rollback



We have a page to let the user insert an object, and then do something else. If a problem occurs after the insert of this object (an exception is thrown in the next lines for example) we rollback to a previously set savepoint.

The object is rollbacked as expected (deleted from the database) but it keeps the ID set by the insert.

Then when we come back to the page to display the cause of the error and to let the user try again, we get  a:

System.DmlException: Insert failed. First exception on row 0 with id 0018000000Yb54RAAR; first error: INVALID_FIELD_FOR_INSERT_UPDATE, cannot specify Id in an insert call: [Id] 


Here is a simple page to test this behaviour:


<apex:page controller="rollTest"> <apex:form> <apex:inputField value="{!acc.name}"/> <apex:commandButton action="{!myMethod}" value="test"/> </apex:form></apex:page>

 And the controller:


public class rollTest{ public Account acc {get; set;} public rollTest(){ acc = new Account(); } public void myMethod(){ SavePoint sp = Database.setSavePoint(); try{ insert acc; Account accFake = [select id from Account where name='testFail']; } catch(Exception e){ System.debug(e); Database.rollback(sp); System.debug(acc.id); } } }


I put a debug after the rollback to show that the ID is kept in the object even if it has been rollbacked.


I thought about putting NULL in the ID but it is read only.


I thought about instantiating a new Object but then we lose all the fields previously entered by the user (of course in reality our object is way more complex than an Account). For now it is the only solution we came with even if it is obviously not acceptable.


To sum up:

A rollback keeps the ID in the object, which causes problems if we try to insert this object again. 


Thanks in advance for any information.







I think I had the same issue, and tried to clone it, but id was also cloned... useless.

I think I copied all values in a new object and switched the object with id to the object without id.


Anybody has better ideas?




You can clone without keeping the ID, if the first parameter is false. (The second parameter is for "deep clone", probably want that as true)



object.clone(false, true);