apex-enterprise-patterns / fflib-apex-common

Common Apex Library supporting Apex Enterprise Patterns and much more!
BSD 3-Clause "New" or "Revised" License
899 stars 514 forks source link

fflib_SObjectUnitOfWork doCommitWork executes all dml for all registered types even if there are no changes #455

Closed bschreibfeder2 closed 1 year ago

bschreibfeder2 commented 1 year ago

Describe the bug When doCommitWork() executes, each stage helper method (e.g. publishBeforeEventsStarting) loops over every registered SObjectType and unconditionally executes its DML statement on the List stored in the stage's Map (e.g. EventBus.publish() called by m_dml.eventPublish(List), even if the List is empty or the SObject type is not appropriate for the operation (e.g. an empty list of a c custom object type is passed to EventBus.publish()). This executes a lot of unnecessary DML calls and creates a large number of internal error log messages in an org executing the method. In particular publishBeforeEventsStarting creates a logged error for every non-e type registered in the UOW on commit.

Can you please wrap the commit statements in an isEmpty() check? e.g. replace

private void publishBeforeEventsStarting()
{
    for (Schema.SObjectType sObjectType : m_sObjectTypes)
    {
        m_dml.eventPublish(m_publishBeforeListByType.get(sObjectType.getDescribe().getName()));
    }
}

with

private void publishBeforeEventsStarting()
{
    for (Schema.SObjectType sObjectType : m_sObjectTypes)
    {
                List<SObject> toCommit = m_publishBeforeListByType.get(sObjectType.getDescribe().getName());
                if (!toCommit.isEmpty()) {
                m_dml.eventPublish(toCommit);
                }
    }
}

This is admittedly a pretty minor bug that normally fails silently unless you're looking through event monitoring logs, but it would be very helpful in reducing splunk noise. Thanks.

To Reproduce

(Please provide a public github repo with a full SFDX project that demonstrates the problem. If the repro case can be followed with a single example Apex class against a scratch org with just the fflib-apex-common and fflib-apex-mocks project deployed into it, you don't need to provide a github repo)

Steps to reproduce the behavior:

  1. Execute any existing positive unit test for fflib_SObjectUnitOfWork.
  2. Observe that all commit stage methods execute DML even if no SObject was added to its List.

Expected behavior DML should not execute on empty lists and empty lists of non-platform event types should not be passed to EventBus.publish.

Screenshots and text of error observed If applicable, add screenshots to help explain your problem. Also, paste the text of the raw error into the issue as well so that it can be found by others via search.

Version Did you try to reproduce the problem against the latest fflib-apex-common code? yes