You need to sign in to do that
Don't have an account?
Dan Blackhall.ax1171
Id's exist on objects after Database rollback
I've created this test controller to illustrate my problem
public class TestController { List<Object_A__c> Aobjects { get; set; } List<Object_B__c> Bobjects { get; set; } public TestController() { //assign values to the a and b lists } public PageReference pageAction() { Savepoint sp = Database.setSavepoint(); try { //Assume this dml operation succeeds insert Aobjects; //assume this dml operation fails insert Bobjects; } catch(System.DmlException e) { Database.rollback(sp); ApexPages.addMessages(e); } } }
When the pageAction is called and there is a rollback because of a problem with 'B objects', the list of 'A Objects' still have Id values.
This becomes a problem when the pageAction is called a second time, because the 'A objects' have Ids and an insert is performed, giving the error: Record ID: cannot specify Id in an insert call
What is the best way to solve this?
No worries, thanks for the quick replies.
The reason there is a rollback is that in my real code this is a wizard that creates the lists of objects, but if there is a database failure none of the objects should remain in the database.
I was able to solve the problem by doing some cleanup in the catch block:
For anyone else reading this, make sure your code is version 23 for this to work because according to the apex docs preserve Id defaults to true for versions <= 22
All Answers
use upsert instead of insert on the a object...
The ID's for a exist because the first time the code ran it was successful. The second time the savepoint and database state are with the new a records so when b fails on the second attempt it rolls back to the start of the second attempt...
That doesn't work, Salesforce tries to update the 'A object' because it has an Id, but the Id does not represent an object in the database because it was rolled back.
The exact error message is:
Yea, sorry about that, you cannot upsert and set an ID for new records so it will fail on the first run unless you are using external ID's...
are B records being inserted correctly the first time? It sounds like they are on the first run as you do not roll back at all since the a records exiost after the first run....
Maybe posting a bit more of your code.....
No worries, thanks for the quick replies.
The reason there is a rollback is that in my real code this is a wizard that creates the lists of objects, but if there is a database failure none of the objects should remain in the database.
I was able to solve the problem by doing some cleanup in the catch block:
For anyone else reading this, make sure your code is version 23 for this to work because according to the apex docs preserve Id defaults to true for versions <= 22
The clone call on a list is a shallow copy; its the deepClone call that copies the SObjects and drops the ids.