+ Start a Discussion
TehNrdTehNrd 

System.SerializationException: Not Serializable: System.Savepoint huh?

Any ideas as to what a SerializationException is? I could not find anything in the documentation.

Code:
Force.com Sandbox

Apex script unhandled exception by user/organization: 00550000000rTQA/00DT0000000EwRY

Visualforce Page: /apex/approveDealReg

System.SerializationException: Not Serializable: System.Savepoint

Class.approveDealRegVF.geterror: line 99, column 13

Debug Log:
***Begining Page Log for /apex/approveDealReg

Element j_id7 called method {!save} returned type PageReference: none20080610195821.020:Class.approveDealRegVF.getforwardOpp: line 76, column 16:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:External entry point:     returning SOBJECT:Split_Credit__c from method public SOBJECT:Split_Credit__c getforwardOpp() in 0 ms
20080610195821.020:External entry point:     returning SOBJECT:Opportunity from method public SOBJECT:Opportunity getexpirationDate() in 0 ms
20080610195821.020:External entry point:     returning SOBJECT:Task from method public SOBJECT:Task getreminderTask() in 0 ms
20080610195821.020:External entry point:     returning SOBJECT:Split_Credit__c from method public SOBJECT:Split_Credit__c getISR() in 0 ms
20080610195821.020:External entry point:     returning SOBJECT:Split_Credit__c from method public SOBJECT:Split_Credit__c getAE() in 0 ms
20080610195821.020:External entry point:     returning SOBJECT:Split_Credit__c from method public SOBJECT:Split_Credit__c getPBM() in 0 ms
20080610195821.020:External entry point:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:Class.approveDealRegVF.getshowRegApproval: line 172, column 16:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:Class.approveDealRegVF.getshowRegApproval: line 172, column 65:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:External entry point:     returning Boolean from method public Boolean getshowRegApproval() in 0 ms
20080610195821.020:Class.approveDealRegVF.getShowFowardApproval: line 180, column 16:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:Class.approveDealRegVF.getShowFowardApproval: line 180, column 65:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:External entry point:     returning Boolean from method public Boolean getShowFowardApproval() in 0 ms
20080610195821.020:External entry point:     returning Boolean from method public Boolean getdisableAccount() in 0 ms
20080610195821.020:External entry point:     returning Boolean from method public Boolean getShowContact() in 0 ms
20080610195821.020:External entry point:     returning Boolean from method public Boolean getreminder() in 0 ms
20080610195821.020:Class.approveDealRegVF.getAccounts: line 201, column 43:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:Class.approveDealRegVF.getAccounts: line 201, column 92:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:External entry point:     returning LIST:System.SelectOption from method public LIST:System.SelectOption getAccounts() in 0 ms
20080610195821.020:External entry point:     returning String from method public String getaccountMergeID() in 0 ms
20080610195821.020:External entry point:     returning LIST:System.SelectOption from method public LIST:System.SelectOption getTerritories() in 0 ms
20080610195821.020:External entry point:     returning String from method public String getTerritoryID() in 0 ms
20080610195821.020:External entry point:     returning String from method public String getprimaryContact() in 0 ms
20080610195821.020:External entry point:     returning String from method public String getbody() in 0 ms
20080610195821.020:External entry point:     returning from end of method public void setaccountMergeID(String) in 0 ms
20080610195821.020:External entry point:     returning Boolean from method public Boolean getShowContact() in 0 ms
20080610195821.020:External entry point:     returning SOBJECT:Opportunity from method public SOBJECT:Opportunity getexpirationDate() in 0 ms
20080610195821.020:External entry point:     returning from end of method public void setReminder(Boolean) in 0 ms
20080610195821.020:External entry point:     returning Boolean from method public Boolean getreminder() in 0 ms
20080610195821.020:External entry point:     returning from end of method public void setTerritoryID(String) in 0 ms
20080610195821.020:External entry point:     returning SOBJECT:Split_Credit__c from method public SOBJECT:Split_Credit__c getISR() in 0 ms
20080610195821.020:External entry point:     returning SOBJECT:Split_Credit__c from method public SOBJECT:Split_Credit__c getAE() in 0 ms
20080610195821.020:External entry point:     returning SOBJECT:Split_Credit__c from method public SOBJECT:Split_Credit__c getPBM() in 0 ms
20080610195821.020:External entry point:     returning from end of method public void setprimaryContact(String) in 0 ms
20080610195821.020:External entry point:     returning from end of method public void setbody(String) in 0 ms
20080610195821.020:Class.approveDealRegVF.save: line 353, column 16:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:Class.approveDealRegVF.save: line 357, column 16:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:Class.approveDealRegVF.save: line 357, column 66:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:Class.approveDealRegVF.save: line 357, column 115:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:Class.approveDealRegVF.save: line 363, column 26: Creating savepoint: SavepointValue0
20080610195821.020:Class.approveDealRegVF.save: line 380, column 51: SOQL query with 3 rows finished in 9 ms
20080610195821.020:Class.approveDealRegVF.save: line 385, column 13: SelectLoop:LIST:SOBJECT:User
20080610195821.020:Class.approveDealRegVF.save: line 400, column 20:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:Class.approveDealRegVF.save: line 400, column 69:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:Class.approveDealRegVF.save: line 410, column 34:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:Class.approveDealRegVF.save: line 417, column 20:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:Class.approveDealRegVF.save: line 417, column 69:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:Class.approveDealRegVF.save: line 435, column 54: Database.convertLead(Database.LeadConvert)
20080610195821.020:Class.approveDealRegVF.save: line 435, column 54:     DML Operation executed in 7 ms
20080610195821.020:External entry point:     returning System.PageReference from method public System.PageReference save() in 23 ms
20080610195821.020:External entry point:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:Class.approveDealRegVF.getshowRegApproval: line 172, column 16:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:Class.approveDealRegVF.getshowRegApproval: line 172, column 65:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:External entry point:     returning Boolean from method public Boolean getshowRegApproval() in 1 ms
20080610195821.020:External entry point:     returning SOBJECT:Opportunity from method public SOBJECT:Opportunity getexpirationDate() in 0 ms
20080610195821.020:Class.approveDealRegVF.getShowFowardApproval: line 180, column 16:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:Class.approveDealRegVF.getShowFowardApproval: line 180, column 65:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:External entry point:     returning Boolean from method public Boolean getShowFowardApproval() in 1 ms
20080610195821.020:Class.approveDealRegVF.getAccounts: line 201, column 43:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:Class.approveDealRegVF.getAccounts: line 201, column 92:     returning SOBJECT:Lead from method public SOBJECT:Lead getsourceLead() in 0 ms
20080610195821.020:External entry point:     returning LIST:System.SelectOption from method public LIST:System.SelectOption getAccounts() in 0 ms
20080610195821.020:External entry point:     returning Boolean from method public Boolean getdisableAccount() in 0 ms
20080610195821.020:External entry point:     returning String from method public String getaccountMergeID() in 0 ms
20080610195821.020:External entry point:     returning Boolean from method public Boolean getShowContact() in 0 ms
20080610195821.020:External entry point:     returning Boolean from method public Boolean getreminder() in 0 ms
20080610195821.020:External entry point:     returning String from method public String geterror() in 0 ms

 


 



Message Edited by TehNrd on 06-10-2008 01:11 PM
dchasmandchasman
That looks to me like you are attempting to hold onto an instance of System.Savepoint in your controller which is going to pull the object into the page's viewstate which is not supported. You can use the transient keyword to declare that your data meber should not be included in viewstate serialization.
TehNrdTehNrd
EDIT: Please see post below.

I looked at the documentation on the transient keyword but I'm not quite sure how to use it. Here is some additional code that appears to be causing the issue.

Code:


Savepoint sp;

String error;
public String geterror(){
return error;
}

public PageReference save() {
//Do some validations on input fields on the VF page
if(accountMergeID == '' || accountMergeID == null){
error = 'Account is required. Please select an option from the Account picklist.';
}

//------------All validations have passed so set a savepoint-------------
if(error == null){
sp = Database.setSavepoint();
}

Database.LeadConvert lc = new database.LeadConvert();
if(error == null){

//setup a lead conversion etc. etc.
if(sourceLead.ownerId != UserInfo.getUserId()){
sourceLead.ownerId = UserInfo.getUserId();
update sourceLead;
}

try{
Database.LeadConvertResult lcr = Database.convertLead(lc);
oppId = lcr.getOpportunityId();
acctId = lcr.getAccountID();
}catch(exception e){
Database.rollback(sp);
error = 'Please contact your System Administrator. An error has occured with the lead conversion: ' + e.getmessage();
}

}
}

 Error is an output panel on the page that would display any issues. It is also worth noting that when this error happens the page gets forwarded to a plain white page with the following text:

Code:
<—xml version="1.0" encoding="UTF-8"–>
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta name="Ajax-Response" content="redirect" /><meta name="Location" content="/apexpages/setup/errorPage.apexp˜core.apexpages.devmode.url=1" /></head></html>




Message Edited by TehNrd on 06-10-2008 06:48 PM
TehNrdTehNrd
The example above may not have been clear enough so I threw together some full code to replicate this error. I hope this can shed some light on the issue or what I am doing wrong:

In addition to these classes and controllers I have also created a validation rule on Contact, IF( AssistantName = null,true, false) , that will cause a DML exception whenever an account is inserted without Assistant.

Code:
PAGE:
<apex:page controller="rollbackerror">
<apex:form >
    <apex:commandButton action="{!save}" value="Save" rerender="error"/>
        
    <apex:outputPanel id="error">
        <apex:outputText value="{!error}"/>
    </apex:outputPanel>
</apex:form>
</apex:page>

CONTROLLER:
public class rollbackerror {

    Savepoint sp; 

    String error;
    public String getError() {
        return error;
    }

    public PageReference save() {
    
        sp = Database.setSavepoint(); 
    
        Account acct = new Account(
            Name = 'Test Account'
        );
        insert acct;
        
        Contact con = new Contact(
            AccountId = acct.Id,
            FirstName = 'Mr.',
            LastName = 'Contact'
        );
        
        try{        
            insert con;
        }catch(exception e){
            Database.rollback(sp); 
            error = 'An error has occured: ' + e.getMessage();
        }
        
        return null;
    }
}

 

TehNrdTehNrd
I'm not sure if this is a bug or me using savepoints wrong but due the the strange behavior of the page I have opened a case for this, 01915160.
SuperfellSuperfell
Make your savePoint local to the method, rather than a class level member.
TehNrdTehNrd
Thanks Simon, one of the reasons I had done it this way is I have numerous steps that need to be rolled back if something failed and the sp needed to be visible to all of the code blocks.....

Code:

Savepoint sp;
public PageReference save() {
//Do some validations on input fields on the VF page
if(accountMergeID == '' || accountMergeID == null){
error = 'Account is required. Please select an option from the Account picklist.';
}

//------------All validations have passed so set a savepoint-------------
if(error == null){
sp = Database.setSavepoint();
}

Database.LeadConvert lc = new database.LeadConvert();
if(error == null){

//setup a lead conversion etc. etc.
if(sourceLead.ownerId != UserInfo.getUserId()){
sourceLead.ownerId = UserInfo.getUserId();
update sourceLead;
}

try{
Database.LeadConvertResult lcr = Database.convertLead(lc);
oppId = lcr.getOpportunityId();
acctId = lcr.getAccountID();
}catch(exception e){
Database.rollback(sp);
error = 'Please contact your System Administrator. An error has occured with the lead conversion: ' + e.getmessage();
}
}

if(error == null){
Do some more stuff

try{
execute some dml
}catch(exception e){
Database.rollback(sp);
error = 'Please contact your System Administrator. An error has occured with the inserts';
}
}

if(error == null){
//Do even more stuff

try{
execute some dml
}catch(exception e){
Database.rollback(sp);
error = 'Please contact your System Administrator. An error has occured with the updates';
}
}
}

It appears I should do it this way instead.....?
Code:
 public PageReference save() {
//Do some validations on input fields on the VF page
if(accountMergeID == '' || accountMergeID == null){
error = 'Account is required. Please select an option from the Account picklist.';
}

//------------All validations have passed so set a savepoint-------------
if(error == null){
Savepoint sp = Database.setSavepoint();


Database.LeadConvert lc = new database.LeadConvert();
if(error == null){

//setup a lead conversion etc. etc.
if(sourceLead.ownerId != UserInfo.getUserId()){
sourceLead.ownerId = UserInfo.getUserId();
update sourceLead;
}

try{
Database.LeadConvertResult lcr = Database.convertLead(lc);
oppId = lcr.getOpportunityId();
acctId = lcr.getAccountID();
}catch(exception e){
Database.rollback(sp);
error = 'Please contact your System Administrator. An error has occured with the lead conversion: ' + e.getmessage();
}
}

if(error == null){
Do some moer stuff

try{
execute some dml
}catch(exception e){
Database.rollback(sp);
error = 'Please contact your System Administrator. An error has occured with the inserts';
}
}

if(error == null){
//Do even more stuff

try{
execute some dml
}catch(exception e){
Database.rollback(sp);
error = 'Please contact your System Administrator. An error has occured with the updates';
}
}
}
}

 






Message Edited by TehNrd on 06-11-2008 10:01 AM
TehNrdTehNrd
Doug/Simon,

Thanks for the help. Changing the code to to have the Savepoint inside the method did the trick.

It still may be worth looking into the code I posted above that throws the error as it is not very descriptive.
Code:
<—xml version="1.0" encoding="UTF-8"–>
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta name="Ajax-Response" content="redirect" /><meta name="Location" content="/apexpages/setup/errorPage.apexp˜core.apexpages.devmode.url=1" /></head></htm
 
Thanks,
Jason




Message Edited by TehNrd on 06-11-2008 11:07 AM
TehNrdTehNrd

dchasman wrote:
That looks to me like you are attempting to hold onto an instance of System.Savepoint in your controller which is going to pull the object into the page's viewstate which is not supported. You can use the transient keyword to declare that your data meber should not be included in viewstate serialization.


This sort of threw me off as I wasn't sure what you were saying when you said data member as I was taught these were global variablse, same thing different name.

Adding the keyword transient before Savepoint sp; also fixed the issues. This is strange because the documentation says savepoints are always transient. (p. 87 of Apex guide)


Code:
CONTROLLER:
public class rollbackerror {

    //This fixes the issue but if savepoints are supposed to be automatically transient why am I having to do this? 
transient Savepoint sp; String error; public String getError() { return error; } public PageReference save() { sp = Database.setSavepoint(); Account acct = new Account( Name = 'Test Account' ); insert acct; Contact con = new Contact( AccountId = acct.Id, FirstName = 'Mr.', LastName = 'Contact' ); try{ insert con; }catch(exception e){ Database.rollback(sp); error = 'An error has occured: ' + e.getMessage(); } return null; } }

 Sorry to keep dragging this out if the issue was resolved but there still appears to be some weird things going on.

EDIT: I've also had my support rep close out my case since the main issue was resolved. So if you guys think this is worth looking into I will leave it in your court. Thanks again for all the help




Message Edited by TehNrd on 06-11-2008 12:39 PM
turbo2ohturbo2oh
just ran into this issue, apparently its still not fixed.
priyanka.mv26priyanka.mv26
We should always declare the variable Savepoint sp inside a method and not outside method. This fixed the issue.
Orchay NaehOrchay Naeh
ran into this issue while tried to use httpresponse as class member, i.e. public HttpResponse res {get; set;}
when i removed it and defined it internally the problem was fixed