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*/);
}