[SalesForce] SOQL dynamic query issue – managed package

Stuck with an issue related to Dynamic SOQL queries in Managed package.

As an example in our package, we have a object and field named as sf_com_bh__Application__c and sf_com_bh__Application_method__c respectively.

Our application has a page which display the records from sf_com_bh__Application_method__c based predefined filters. Admin from subscriber org can create their own custom fields and add it to the filter via some configuration.

Things works fine until subscriber's create a custom field with same name as from the package, lets say Application_method__c.

Basic query would then look like:

SELECT Id FROM sf_com_bh__Application__c WHERE 
(sf_com_bh__Application_method__c LIKE :keyword OR 
 Application_method__c LIKE :keyword) 
LIMIT 100

Tried to set the context, now problem is that the above query totally neglects the custom field created by subscriber in where clause.

Also unfortunately our customers cannot change the field api name as its being used in their integration.

Please share some thoughts or workaround, if any.


Following links mentions that in such scenario query it will give preference to subscriber's field instead of from the managed package, in today's date it is not correct. Has Salesforce reversed the implementation such that now all fields in dynamic soql refer to the packaged field; if subscriber has the field with same name?

  1. Idea: Support Dynamic SOQL "No Shadowing" Option
  2. Related question: Dynamic SOQL Queries and Managed Namespaces).

Best Answer

This is a documented "feature" (though I can't seem to find it right now). A managed package cannot reference custom objects or fields created by a subscriber with the same name as a custom object or field by the same name. The reason why is that because the compiler automatically resolves these references to the managed package version. This is done as a convenience to developers so that they don't need to include the namespace in their code everywhere.

In other words, despite what you think, the query actually looks like this by the time the SOQL is executed:

SELECT Id FROM sf_com_bh__Application__c WHERE 
(sf_com_bh__Application_method__c LIKE :keyword OR 
 sf_com_bh__Application_method__c LIKE :keyword) 
LIMIT 100

Obviously, this won't work like you expected. You need to tell the subscribers that they cannot use the same name as a custom field on the object.

This behavior works both ways. Local fields will be described preferentially in subscriber code, but the managed package field will be described preferentially in the managed code. This design is intentional; it allows a package and a namespace to not conflict with each other.

Related Topic