Consider the following two classes. The first has simply a private Test__c
and its constructor fills it in. The second class uses the first one and creates a Test__c
object before instantiating the B class, just for demonstration.
public with sharing class A {
private Test__c tst;
public A (Id id) {
this.tst = [select id, text__c from Test__c where id = :id];
}
public void saveTst () {
update this.tst;
}
}
public with sharing class B {
public B () {
Test__c tst = new Test__c();
insert tst;
A a = new A(tst.id);
a.tst.text__c = 'test';
//update a.tst; // if used, this line produces "Error: Compile Error: Variable is not visible: tst at line 9 column 16"
a.saveTst();
}
}
Now, what I would expect is that the sObject cannot be accessed from the outside (it's private) and that this would apply, of course, to its fields as well. However, although the first part is true and update a.tst
will result in a compile error (as shown in the comment), the line before the commented one works! It is possible to set the private sObjects field and it will be committed to DB.
So, this obviously seems to be a huge bug. What I'm interested in is how did it happen. Are sObjects used in some specific way, possibly parsed out of the code together with fields in advance, so that the modifier gets ignored?
The extra annoying part is that even the update a.tst
part will work if I put the classes in an anonymous block (tried in dev console). I know classes in anonymous are treated as inner classes, but why would that matter here? That tst
is still private to the A class!
Anyone less confused than me?
EDIT: After quite a bit of time wrestling with SF support, the issue was finally propagated to R&D and recognized as a bug: https://success.salesforce.com/issues_view?id=a1p30000000T22eAAC