AggregateRoot as CommandHandler vs Dedicated CommandHandler

I have read several threads about the two modes of CommandHandler that provides Axon; directly from AggregateRoot and to have a dedicated CommandHandler.

I have a question about, I have some commands that do not change the state of the Write Model, and not even need to validate the Domain Model, they serve only to Read Model.

Using the same AggregateRoot as commandHandler the AggregateRoot is automatically re-hydrated from the events stored, instead using a separate CommandHandler I could avoid rehydration and launch its event directly from CommandHanlder improving performance.

What do you think, I’m off the road, I’m forgetting or underestimating some principle?

Finally, if this practice is not forbidden how do I raise an event from commandHandler ?, I have to import the commandBus in the CommandHandler?

Regards

Hello Pietro,
what are you actually trying to do? Usually you would send a command in order to change some state, if your command doesn’t change any state, why don’t you simply use a method call?

Cheers,
Paul

Yes, I believe there is a need for an example:
this is my AR:

`
public class Candidate extends AbstractAnnotatedAggregateRoot {

@AggregateIdentifier
private CandidateId candidateId;
protected Candidate() {}

@CommandHandler
public Candidate(final CreateCandidateCommand command) {
apply(CandidateCreatedEvent.create(command.getCandidatoId(), command.getUserId()));
}

@EventHandler
private void handleCreated(final CandidateCreatedEvent event) { // This event changes the AR’s state
this.candidateId = event.getCandidateId();
}

@CommandHandler
private void AddFreeUnimportantText(final AddFreeCommentCommand command) {
apply(FreeCommentAddedEvent.create(candidateId, command.getText())); // This event require only Read Side update, for which I would not rehydrate the AR from EventStore
}

`

Obviously the method, commands and events names are fictional, they only serve to give an idea

I hope that my request is now clearer

Hi Pietro.

I understand your point of view.
If FreeComment ‘belongs’ to that Candidate, having the method directly on it guarantees, for example, that if the Candidate has been deleted (markDeleted), the event will not raised.
However, even though I’ve never done, I think that you can always inject EventBus in your dedicated CommandHandler and invoke a publish on it without loading the Aggregate.

Simone.

What if you do it with a standard Command?

I understood the information is needed only by the read model but are you sure you'll never need this event in the future?

If you really don't want to save the event in the eventstore why don't you update the read model without involving the aggregate?

Hi Pietro,

can you update a “FreeComment” for a Candidate that doesn’t exist? A simple command handler will not be able to do that type of validation.

If you want to publish events directly from a command handler, and not store them, you can best use the EventTemplate. It ensures that events are nicely published as part of the unit of work. This, in turn, guarantees that events are published in the correct order, should you have any event handlers that send commands, which send more events, etc. etc.

Hope this helps.
Cheers,

Allard

Thanks for your all reply, I’ve got your points, I understood it could be done, but as all of yous suggests I’ll avoid that.

Thanks