+ Start a Discussion

changes not preserved when passing sObject back to parent method

I have two methods within the same class that pass a generic sObject, like so...

public void updateRecord(sObject s){

/*...do some stuff...*/

//check if s is a Lead and if so try to convert
Boolean yay = this.tryToConvertLead(s);

/*...do some more stuff */


public void tryToConvertLead(sObject cl){
/*...tries to convert the lead...*/
//if converted
if (convertSuccess) cl = [Select ID,... FROM Contact Where Id IN (Select ConvertedContactID From Lead Where IsConverted=true AND Id = :cl.Id];


My understanding was that sObject instances are automatically passed by reference and that because of this I don't need to explicitly pass back the sObject that has now been assigned a fresh record, but this is not working.


Is this because it's what i'm passing is a generic sObject and not a specific sObject (ie Lead / Contact)?

Is this some nuanced behavior where the passing by reference aspect actually applies to the record rather than the declared instance (cl / s)?

Have i just missed something idiotic?


Thanks for any help!




The SObject is passed by reference, yes. However, in your method you are reassigning your SObject reference to a different record, which sort of breaks the connection with that original SObject parameter.


If you just changed a field in the 'cl' object, that change would be retained, but redefining cl as something different altogether won't work. I think this behavior is what you mean by the reference applying directly "to the record rather than the declared instance".


In your case, you may want to do your Contact query after returning from the tryToConvertLead method, or pass back a Contact or Contact ID with your return statement.




Thanks for the quick confirmation.


I had a feeling but I was really hoping that wouldn't be the case.


To answer your why... it just simplifies things when specific triggers and classes call dynamic-apex based utility classes and when developing logic that handles groups of related objects that span multiple object types, not to mention static methods that can't as easily store things up to the class properties.


but alas. back to public sObject method (sObject s)...


In this respect, Apex behaves just like Java.  The same workarounds apply as well.  You can pass in an array of sobjects:



void doSomething(Sobject[] objs) {
  objs[0] = [select ... where id = :objs[0].id];



then the calling code will see the new value of objs[0] when the method returns.