6

Does anyone know how to reference a non-namespaced object from a namespaced context when the two names collide?

I'm dealing with a codebase that uses both EDA and EASY, and EASY has an Application__c object I want to use EDA's TDTM for, but EDA doesn't seem to like that since it also installed a hed__Application__c object and is getting confused by what I meant when I said Schema.SObjectType.Application__c inside its hed.TDTM_Global_API.run() method.

trigger ApplicationTrigger on Application__c (after delete, after insert, after undelete, after update, before delete, before insert, before update) {
    hed.TDTM_Global_API.run(Trigger.isBefore, Trigger.isAfter, Trigger.isInsert, Trigger.isUpdate, Trigger.isDelete, Trigger.isUndelete, Trigger.new, Trigger.old, Schema.SObjectType.Application__c);
}
Message: System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, ApplicationTrigger: execution of
                    BeforeInsert

                    caused by: System.TypeException: Invalid conversion from runtime type List<Application__c> to List<hed__Application__c>
3
  • 3
    You might need to go to more extreme lengths to disambiguate such as Schema.Application__c.sObjectType.getDescribe() instead.
    – Adrian Larson
    Feb 5, 2022 at 3:30
  • 4
  • I was afraid of that, @Raul -- you're right, Schema.Application__c.sObjectType.getDescribe() didn't help. I'm pretty sure it shouldn't even be happening because all "Trigger Handler" records should be nonexistent in unit tests until turned on (turns out it's a specific packaged Application__c handler erroring out), but EDA bug. So maybe I'll just make a whole different trigger handler dedicated to Application__c and call it instead of hed.TDTM_Global_API.run() from ApplicationTrigger for now.
    – k..
    Feb 5, 2022 at 13:56

1 Answer 1

1

It seems, in your comment, this is happening to you in an unit test. That scenario is called out in EDA Disable Trigger Handlers

Sometimes it's necessary to temporarily disable specific Trigger Handlers only during the execution of Apex code. For example, you should do so at the start of unit tests when there’s a custom object in your org with the same API name as one released by EDA (such as Application__c) and a TDTM Trigger Handler for that object.

You'll have to do either of the following:

  1. Create a trigger handler record for your custom class in your test before inserting your application records (so that EDA won't auto create default handlers)
hed__Trigger_Handler__c newTDTM = new hed__Trigger_Handler__c(
    hed__Active__c = true,
    hed__Asynchronous__c = false,
    hed__Class__c = 'ApplicationTrigger',
    hed__Load_Order__c = 1,
    hed__Object__c = 'Application',
    hed__Trigger_Action__c = 'AfterInsert;AfterUpdate',
);
insert newTDTM

//start test and insert test data
  1. Disable the EDA Trigger Handlers in unit tests. Below, is the code snippet from documentation if you'd like to disable a specific class, specific object, or all EDA-provided trigger handlers.
for (hed.TDTM_Global_API.TdtmToken tdtmToken : hed.TDTM_Global_API.getTdtmConfig()) {       
    // disable for a specific trigger handler class
    if (tdtmToken.className == 'Application_TDTM') {
        tdtmToken.active = false;
    }
    // disable for an entire object
    else if (tdtmToken.targetObject == 'Contact') {
        tdtmToken.active = false;
    }        
    // disable all EDA-provided trigger handlers
    else if (tdtmToken.ownedByNamespace == 'hed') {
        tdtmToken.active = false;
    }     
}

Why are the EDA trigger handlers running in test context and why does the above work?

Since Trigger Handlers are records, they wouldn't exist in test context. As such, every Trigger Handler makes a call to TDTM_Config.getClassesToCallForObject() which calls getTdtmConfig(). For that method, the description is

@description Returns the TDTM configuration. If no configuration is currently set, it will return the default configuration without setting it. The configuration returned has not yet been inserted in the database. It can be manipulated, if necessary, then set. If no configuration exists, the application will insert the defaults when any of the triggers run.

@return List<TDTM_Global_API.TdtmToken> List of trigger handler tokens with the default values.

You'll see within that method the following call

// Getting the default configuration only if there is no data in the Trigger Handler object. Otherwise
// we would delete customizations and Trigger Handlers entries that aren't in the default configuration.
if(tdtmConfig.size() == 0) {
    tdtmConfig = TDTM_DefaultConfig.getDefaultRecords();
}

TDTM_DefaultConfig lists out the default trigger handlers that will be inserted in test context should none be defined (all the ones packaged by EDA). Hence, both options listed above will work as if a record already exists - it won't create the defaults. Otherwise, you have the ability to deactivate any defaults you'd like for the purpose of your test.

1
  • That is absolutely BONKERS that EDA Trigger Handlers are enabled by default in unit tests and need to be disabled in test setup to make unit tests behave unit-test-like, rather than needing to be enabled in test setup to make unit tests behave EDA-like, and one of those supremely irritating things where a corporation insists "It's a feature, not a bug!" but you know in your heart that it's a glaring bug. Nevertheless, I marked this the correct answer because it clearly is -- thanks so much for your help, as frustrated as I am by the EDA codebase's uncourteous behavior!
    – k..
    Feb 18, 2022 at 14:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .