1

I can't get FFLIB uow to work with a self-relationship field. Quick use case: Create two accounts and relate the second one with the first one using a custom lookup field (selfRelation__c)

fflib_ISObjectUnitOfWork uow = Application.unitOfWork.newInstance();

Account account1 = new Account();
account1.name = 'account1';
uow.registerNew(account1);

Account account2 = new Account();
account2.name = 'account2';
uow.registerRelationship(account2,Account.selfRelation__c,account1);
uow.registerNew(account2);

uow.commitWork();

and as a result, both accounts are created but the relation was not defined.

Any feedback?

Thanks

1 Answer 1

2

This isn't supported in the same Unit of Work - why?

Because both registerNews are collected into a single collection of Account by fflib_UnitOfWork and inserted in a single DML statement. registerRelationship only adjusts object references in memory - it does not do separate DML on its own.

Thus, the Id for account1 isn't yet known to set the lookupfield on account2

You need to do this in two units of work each with their own commitWorks(). That is, registerNew account1 in uow1, then commitWork, then registerNew/registerRelationship account2 in a new instance of uow, and commitWork on that uow.

Note also, the following four lines can be collapsed into one

Account account2 = new Account();
account2.name = 'account2';
uow.registerRelationship(account2,Account.selfRelation__c,account1);
uow.registerNew(account2);

to

uow.registerNew(new Account(Name = 'account2),
                Account.selfRelation__c,
                account1);

as registerNew has an overloaded signature

Worth buying if you haven't already Salesforce Lightning Platform Enterprise Architecture by Andrew Fawcett 3rd edition (4th edition is in progress from what I hear) - page 181 Unit of Work Special Considerations

... not supported ...

Self and recursize referencing

Partial success Database operations

Sending emails -- this is now supported after the release of the 3rd edition thanks to the open source community

3
  • As a brief aside: It is technically possible to do with one UoW instance, but that would require the parent and child records to be in different trigger chunks (meaning you'd need at least 201 records to insert). >99% of the time, that condition isn't going to be met, so using 2 UoW instances is the way to go (unless you want to modify/extend fflib's implementation).
    – Derek F
    Mar 30, 2023 at 16:52
  • @DerekF - I never thought about that; clever(?!) but fragile.
    – cropredy
    Mar 30, 2023 at 16:58
  • Definitely fragile and "clever programming". On further inspection, my assertion isn't true for fflib's UoW because it only maintains a single list per SObject (as you noted) and only makes one call to resolve() before performing DML. I imagine it wouldn't be too much of a pain to add single-level self-relationship support, but just using two instances is the simpler solution.
    – Derek F
    Mar 30, 2023 at 17:16

You must log in to answer this question.

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