Hi Victor,
Like I said, it’s fine to ask questions. That’s what this forum is for.
Thank you so much,
The event handler at the constructor is going to set at least the initial state of the instance doing that is the only command handler that mutates/initiates the aggregate.
Your first comment however puts me off again. Maybe a code snippet would clarify in this space if I don’t understand you correctly.
Any how, if you’re going to do Event Sourcing, so use the EventSourcingRepository
for your Aggregates (this is Axon’s default by the way), then changing state in a command handler will end up with an exception.
So setting any fields in a command handler is out of the questions. That’s were the @EventSourcingHandler
annotated functions are for.
The event you’d apply in your Constructor Command Handler, lets call it AggregateCreatedEvent, would be handled by an @EventSourcingHandler void on(AggregateCreatedEvent event) { ... }
function and that is were you’d set any id’s/fields you can from the event.
- should I set the Id in the constructor command handler or wait for the event and be nullable?
You should wait for the event sourcing handler of the event you publish in your constructor command handler to set the aggregate identifier.
- the aggregate instance is visible to receive further commands after the constructor of after the creation event handler?
An aggregate will be visible if the UnitOfWork has rounded up the whole process of command/event handling. Only if everything succeeded, will the events be persisted. Once that’s happened other commands can be published against it.
- as Troy Hard said, should I use to nulls to determine the state of my aggregate? how this play with replays and snapshots? could that lead to incorrect invariants?
That wholly depends on the decision making process you let your command handlers go through. If you want to ensure a field is not null when the command arrives, then a null check is more than valid. If you’d however want to ensure a certain value is greater than X, then your decision making process (read: the assertion) should be just that.
- Troy used Spring or Axon Assert, that throws and exception on fail. do you
recommend to use exceptions on events to deal with failure checking invariants?
This depends on what kind of notice you want to give the command publisher. If you want to silently ignore it’s command, then a normal return;
statement would suffice. If the command publisher however did something terrible in terms of the published command, then an exception might be in place.
Sorry for the amount of questions, this is the first time I try to design a system in this way. Aggregates seems really different (command receivers, event listeners, state machine) vs cluster of domain objects that can be treated as one.
Hope this helps you out further Victor!
Cheers,
Steven