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
trmptrmp 

Using Database.rollback routes to Data Not Available error

I have a custom save method that sets a Savepoint, does some inserts and either rolls back (using Database.rollback) if there's an error or redirects to one of the newly inserted records. I just started testing the roll back functionality and it is not working as I would expect. The insert is in fact rolled back, but instead of being sent back to the Visualforce page I was just on, I am sent to a Salesforce error page saying "Data Not Available". It seems to me like the roll back might be removing the view state of the Visualforce page or something strange.

 

public PageReference save() {
	Savepoint beforeInserts = Database.setSavepoint();
	if (trySave() == true) {
		return (new ApexPages.StandardController(record)).view();
	}
	Database.rollback(beforeInserts);
	return null;
}

private boolean trySave() {
    //do some validation and such
    try {
        insert record;
    }
    catch (Exception err) {
        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, err.getMessage()));
        return false;
    }
    return false; //to test the roll back
}

 Has anyone seen something like this?

 

Thanks!

Ispita_NavatarIspita_Navatar

Hi trmp,

Database.rollback(beforeInserts) should be invoked by you in the catch block for roll back functionality.Use the following code snippet in your code and let me know if it works.

                                                 

              catch (Exception err)

              {

              ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, err.getMessage()));

              Database.rollback(beforeInserts) // This method might be invoke here.

              return false;

             }

 

Did this answer your question? If not, let me know what didn't work, or if so, please mark it solved.

trmptrmp

Ispita,

 

That is not the problem. The problem is that any subsequent DML exception after the first insert succeeds does not redirect appropriately after doing the roll back. Instead of being returned to the Visualforce page I started from, I end up at the Data Not Available page. I am probably going to have to log a case for this.

 

Thanks.

DevNVDevNV

I'm seeing this same issue - trmp did you resolve this yet?  Would love to hear what the issue is.  

trmptrmp

Unfortunately, I have not. I have sort of worked around it instead of having to deal with logging a support case. I basically do any validation I want before setting the save point. But if for some unexpected reason the insert fails, I don't have a solution for this. I might open a support ticket on this if it becomes an issue. Sorry I don't have a better answer. :-/

DevNVDevNV

I figured out my problem - not sure it's the same as what you are doing but the solution might shed some light.  I was using the controller.save() method to save a parent Quote record, then did some more processing and inserted Quote Line Items.  Finally I returned the page reference given by the controller.save() method called earlier.  In the catch block I was just returning null.

 

I think using the controller.save() method confused the VF page.  When I removed that and used the basic insert DML call returning the controller.view(), the exception block's rollback and return of null worked!

 

Before code that bombs if QLI validation rules fail the insert - takes me to the VF page but with 'Data Not Available' VF error message:

 

    public PageReference save() {
		Savepoint sp = Database.setSavepoint();
        try{   
		// insert the quote using the standard save method
	        PageReference p = controller.save();

	        // now do other things, including updating that same Quote record
	        update q;
	        // and inserting some Quote Line Item rows
	        if(items.size() > 0) insert items;
	        // Return the page reference from the save method
        	return p;	        
        }
        catch(Exception e2){
            ApexPages.addMessages(e2);
            Database.rollback(sp);
            return null;
        }   
    }

 After update - failure takes me to the VF page with the page message and all is good.

 

    public PageReference save() {
		Savepoint sp = Database.setSavepoint();
        try{   
		// insert the quote using the insert method
	        insert q;

	        // now do other things, including updating that same Quote record
	        update q;
	        // and inserting some Quote Line Item rows
	        if(items.size() > 0) insert items;
	        // Return the page reference from the save method
        	return controller.view();	        
        }
        catch(Exception e2){
            ApexPages.addMessages(e2);
            Database.rollback(sp);
            return null;
        }   
    }

 

Hope that helps you somewhat.

trmptrmp

Have you tested this where the Quote insert is successfull but the QLI insert fails? This is where I am having the issue. The rollback after DML success then DML failure (even when returning null) sends me to Data Not Available.

 

[Edit] I'm not using controller.save(). I am using the standard insert DML call that you show in your second set of code.

DevNVDevNV

Yes, my error happens in the line items, not the original Quote save. 

 

I did see you are already using the DML insert which is why I wasn't sure my solution would help but thought it might give you another idea.

KMForceKMForce
HI @DevNV,
        Is there any way to not go for custom upsert and we could use standard Save? 
Thanks.
boozbooz
Hi,

I also encountered this weird error on Database.rollback method. I found out that the Data Not Available error page is displayed because salesforce thinks that you're accessing a record which is deleted somewhere else while processing the code. This is because the id field of record variable is not cleared when you call Database.rollback. I manage to prevent the error by setting the id of the troublesome variable to null as shown below:
 
private boolean trySave() {
	    //do some validation and such
	    try {
	        insert record;
	    }
	    catch (Exception err) {
	        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, err.getMessage()));
	        record.Id = null; //To prevent the Data Not Available error
	        return false;
	    }
	    return false; //to test the roll back
	}