Multi-Entity Aggregate Best Practices : when to create the first entity

The Axon documentation recommends adding new entities to an aggregate through the EventSourcingHandler…

from: Multi-Entity Aggregates - Axon Reference Guide

The creation of the Entity takes place in an event sourcing handler of it’s parent.
It is thus not possible to have a ‘command handling constructor’ on the entity class as with the aggregate root.
(sic: note the apostrophe in “it’s” is a typo)

But when/where do you create the initial entity?

Your GiftCard aggregate starts with no entities. We have a similar model but want an initial entity to be created when the aggregate is created. e.g. imagine if a new GiftCard always came with a “default” GiftCardTransaction.
Where would you do this?

a) in the constructor of the GiftCard:

     public GiftCard(IssueCardCommand cmd) {
        ... 
        // problem: never gets replayed!
        transactions.add(new GiftCardTransaction(/*defaults*/)

b) in the initializing event handler

    public void on(CardIssuedEvent evt) {    // initialize aggregate
          // create the first entity
          // gets replayed when the aggregate creation is replayed
         transactions.add(new GiftCardTransaction(/*defaults*/)
    }

c) in the event handler but by firing the event

    public void on(CardIssuedEvent evt) {     // initialize aggregate
           // fire the event to create the first entity
          // problem: gets replayed twice: when the aggregate creation is replayed and the subsequent event is replayed!!?
          apply(new CardRedeemedEvent(/*defaults*/);
       }

d) same as c but use an annotation to prevent the double replay:

    public void on(CardIssuedEvent evt) {    // initialize aggregate
          // call a non-replayable method to fire the event
          createFirstEntity();
     }
    
    @DisallowReplay  
    public void createFirstEntity() {
          // The replay of this CardRedeemedEvent will create the first entity on replay, 
          // but the replay of the CardIssuedEvent will not, thanks to the @DisallowReplay... right??
          apply(new CardRedeemedEvent(/*defaults*/);
     }

hi @rhubarb, welcome to the forum!

Creating the entity should be done using the @EventSourcingHandler, in your example option b. The state changes should happen here, and the first Event Handler should set the Aggregate Identifier. Here’s a reference to the Aggregate documentation.

Hope this helps with the aggregate creation entity.

Thanks Vaishnavi … that sounds like the right answer but I just want to double check that it applies to this specific use case: I’m not asking about where to generally create entities, but where to create the FIRST entity.
I understand that entities would be generally created and added in the @EventSourcingHandler for the event that creates the entity, but note that my option b is creating the first entity in the handler for the _event that creates the Aggregate
Is that correct?

MOVED TO STACKOVERFLOW

Sorry for the redirect - I thought SO was the wrong place for this sort of question, but in retrospect there’s a lot of healthy discussion there on understanding aggregates.

@Vaish_Sriram, please note that I now think c. is the correct answer…

Let me elaborate a bit more on my answer on StackOverflow. When you use then eventsourcing repository, the Aggregates are sourced from the Events. You can see the following happening when using option B:

IssueCardCommand → instantiates a new instance of the GC aggregate.
In the constructor, a CardIssuedEvent is applied.
The CardIssuedEvent EventSoursingHandler will be invoked and the entity will be created.
After that, the transaction ends if there is no more logic to perform in the constructor.

So option B is the way to go and the entity is created.

I hope this helps,

Yvonne