Problem with After Update query
g1b3r opened this issue · 6 comments
Expected Behavior
Trigger should works
Actual Behavior
AccountTrigger: execution of AfterUpdate caused by: System.TypeException: TA_Account_After_Update_Queries does not have a no-arg constructor (System Code) Class.MetadataTriggerHandler.executeActions: line 190, column 1 Class.MetadataTriggerHandler.afterUpdate: line 40, column 1 Class.TriggerBase.run: line 81, column 1 Trigger.AccountTrigger: line 17, column 1
Steps to Reproduce the Problem
Specifications
`public with sharing class TA_Account_After_Update_Queries {
private static TA_Account_After_Update_Queries instance;
private TA_Account_After_Update_Queries() {
}
public static TA_Account_After_Update_Queries getInstance() {
if (TA_Account_After_Update_Queries.instance == null) {
TA_Account_After_Update_Queries.instance = new TA_Account_After_Update_Queries();
}
return TA_Account_After_Update_Queries.instance;
}
public Map<Id, Case> afterCaseMap { get; private set; }
public class Service implements TriggerAction.AfterUpdate {
public void afterUpdate(List<Account> newList , List<Account> oldList) {
TA_Account_After_Update_Queries.getInstance().afterCaseMap = getAllCasesFromAccounts(newList);
}
private Map<Id, Case> getAllCasesFromAccounts(List<Account> newList) {
Set<Id> accIds = new Set<Id>();
for (Account myAcc : newList) {
accIds.add(myAcc.Id);
}
return new Map<Id, Case>(
[SELECT Id, Subject FROM Case WHERE AccountId IN :accIds]
);
}
}
}
`
`public class TA_Account_AfterUpdates implements TriggerAction.AfterUpdate {
public void afterUpdate(List<Account> newList, List<Account> oldList) {
Map<Id,Account> oldMap = new Map<Id,Account>(oldList);
Map<Id, Case> caseIdtoAcc = TA_Account_After_Update_Queries.getInstance().afterCaseMap;
Map<Id, Account> accountId2Case = new Map<Id,Account>(newList);
for (Account aList : newList) {
if ( TriggerBase.idToNumberOfTimesSeenAfterUpdate.get(aList.id) == 1
&& aList.Name != oldMap.get(aList.id).Name
) {
CaseHelper.createCaseAfterAccountRename(accountId2Case);
}
}
}
}`
I think this should works or maybe im wrong. I just tried to implement this pattern (which is looks amazing). Can you please check that ?
Metadata are configured and set with order 0 and using after update on account
- Version: latest
- Platform: mac
my bad :)
i deleted by mistake a custom md and started working but after that map is empty
I think your issue is caused by referencing the TA_Account_After_Update_Queries
class in the Trigger_Action__mdt
record, instead of the inner TA_Account_After_Update_Queries.Service
class.
Separating this into an inner class is necessary to support the singleton pattern because singletons can't be instantiated using the Type.forName
mechanism. The top level class is the singleton and the inner Service
class enables it to be used in the framework.
There are a few additional opportunities to improve here:
- Use one class for all queries on a given Sobject:
TA_Account_Queries
, don't separate into multiple singletons for each context. - Don't dispatch the logic to
CaseHelper
, perfom all of the logic in the trigger action itself so it's easier to understand and you can useaddError
on the parent account if a case DML operation fails. - When all of your logic is in the trigger action, you might want to change the name of your trigger action to something like
TA_Account_MakeRenameCase
.
Thank you thats helps me a lot :-) So using this framework i should rather create a more classes where will be executed different logic ? :-) I already create a proper query class and this is looks amazing :)
Correct, we want multiple classes, each with a single responsibility or reason to change.
The best analogy I can make is this: if you were a chef, the legacy way of writing triggers is like writing all of your recipes all together on one long scroll. With the Trigger Actions Framework, you are writing your recipes on their own index cards. It makes it much easier to understand a single recipe, and to sort/organize them however you best see fit.
Thank you for your help :) Good job with this framework :)