Skip to content

Child Commands

Gal Koren edited this page Nov 12, 2020 · 1 revision

We saw how to define relations on the Relations page.
We saw how using a FieldComplexValidator, an entity can validate against fields of related entities. Not only validators can access related entities, but all state consumers as described here.

We now want to execute a parent and a child together within the same command:

  • If the child validation fails, we want to fail the parent.
  • We want the parent ID to be automatically populated into the child.
  • We might want to replace the entire set of children given a new set.
  • We want cascade deletion.

Suppose defined two entities already: an AdEntity (child) and a CampaignEntity (parent).
Suppose the AdEntity has a CAMPAIGN_ID field referring to the CampaignEntity.
Let's see what we can do.

Setup the Flow

We first need to add the child flow into the parent flow as follows:

public class CampaignPersistence {
    /* ...code... */

    ChangeFlowConfig.Builder<CampaignEntity> campaignFlow() {
        return ChangeFlowConfigBuilderFactory
           .newInstance(plContext, CampaignEntity.INSTANCE)
           .withChildFlowBuilder(AdPersistence.adFlow()); // <------ Child
    }
}

Adding child commands

var campaignCmd = new CreateCampaignCommand();

campaignCmd.addChild(adCommand1);
campaignCmd.addChild(adCommand2);
campaignCmd.addChild(adCommand3);

var results = campaignPersistence.create(asList(campaignCmd));

Remember you don't need to populate the CAMPAIGN_ID field of the Ad commands. Every Ad field referring to the Campaign is populated automatically.

Replacing children

In this scenario, you have a list of Ads and you want to do the following:

  • If the Ad already exist in the campaign, then just update it.
  • If the Ad does not yet exist in the campaign, then insert it.
  • Any other Ad not in the given list shall be deleted from the campaign.

For the first two requirements, you just need the Ad command to be an InsertOnDuplicateUpdateCommand. For the deletion part, you need to add a DeletionOfOther to the Campaign command as follows:

campaignCmd.add(new DeletionOfOther(AdEntity.INSTANCE));

If you have a custom deletion logic, suppose you only want to mark them as deleted somehow, then you can implement a different type of MissingChildrenSupplier rather than DeletionOfOther.