Avoiding a “Methods cannot be marked transient” compilation error

I recently needed to make an SObject field transient in a series of Apex wrapper objects used in a controller for a sequence of Visualforce wizard pages. Why is a whole other story.

Here is a simplified example of one of the wrappers:

public class ActionWrapper {
    public Action__c sob { get; private set; }
    public ActionWrapper(Action__c sob) {
        this.sob = sob;
    }
    // ...
}

Given the large amount of code that depended on these objects I wanted to hide the fact that the SObject field would be null each time a wizard page was posted and so tried code of this pattern (though with the SOQL done in bulk not in each get):

public class ActionWrapper {
    public transient Action__c sob {
        get {
            if (sob == null && sobId != null) {
                sob = [select ... from Action__c where Id = :sobId];
            }
            return sob;
        }
        private set {
            sob = value;
            sobId = sob.Id;
        }
    }
    private Id sobId;
    public ActionWrapper(Action__c sob) {
        this.sob = sob;
    }
    // ...
}

But this yields the error “Methods cannot be marked transient”: it looks like compilation of get or set without a body is handled differently from get or set with a body. Pretty discouraging…

The good news is that the following pattern solves the problem by separating the transient declaration from the get and set methods:

public class ActionWrapper {
    public Action__c sob {
        get {
            if (sobValue == null && sobId != null) {
                sobValue = [select ... from Action__c where Id = :sobId];
            }
            return sobValue;
        }
        private set {
            sobValue = value;
            sobId = sobValue.Id;
        }
    }
    private Id sobId;
    private transient Action__c sobValue;
    public ActionWrapper(Action__c sob) {
        this.sob = sob;
    }
    // ...
}

5 thoughts on “Avoiding a “Methods cannot be marked transient” compilation error

  1. Actually this aproach doesn’t work. The field with complex getter and setter can NOT ultimately be maked transient – that is, such a field IS saved in viewstate, serialized to json etc. Adding another transient field that stores actual value doesn’t eleiminate the source field and its serialization. So, the only way that seems to do that is to get rid off the property completely by REPLACING it with getter and setter accessing private transient field.

      • Exactly. The wrapper has property ‘sob’ that is accessed via methods but is never actually set. It is serialized because it is not transient and, yes, it is serialized as null since it is always empty. I mean that serialized wrapper cannot be completely clean if property is at least declared.

  2. Keith — ran into this today and found this post useful. I must admit when I saw the variable name `sob`, I first read it as `son of a b…` which is how I felt when I ran into the aforementioned compile error. A doubly useful variable naming convention. …crop1645

Leave a reply to Force 201 Cancel reply