Added ToDoCommandHandler to Axon tutorial, but doesn't work

Hi Viggo,

obviously, the event store only adds the newly created events. Those are the event that have been generated by the command you’re sending.

The reason you see the system out each time, is because commands always execute against the latest state of an aggregate. How do you know the latest state? By replaying all events that happened earlier. To do so, Axon invokes all the @EventHandler methods for the events that happened before. These methods are responsible for applying the state change that belongs to the event.
If you put system out in your @EventHander methods, you will see all the system outs generated by the replaying of history first, and then the system outs of the newly added events. If you put a system out in the command method of an aggregate (either the @CommandHandler annotated method or the method on the aggregate that the external command handler invokes), you’ll see which system outs belong to the history being replayed and which belong to newly applied events.

If you can email the implementation of ToDoItem and the configuration, I can have a look at it.

Cheers,

Allard

Thanks Allard, I get your message about the “created events” vs the output in the event handlers:)

Email sent with project to be looked at!

Thanks:)

Hi Viggo,

looking at the code, everything became clear to me.
There are 2 classes with @EventHandler methods in them. The first is ToDoItem, which is an aggregate root. It has only one @EventHandler, which handles ToDoItemCreatedEvent and prints “We’ve got something to do …”.
The other class is a regular event handler that listens to events from the Bus. This handler receives each event once.

So when loading an aggregate, the @EventHandler inside the aggregate will print its line.

So the output you get is exactly as expected:

We’ve got something to do: Need to do this (19d7cf6a-d252-4e7d-9d85-51f7249fd13e) <-- printed by the aggregate as it’s newly applied
We’ve got something to do: Need to do this (19d7cf6a-d252-4e7d-9d85-51f7249fd13e) <-- printed by the aggregate as it’s building state from history
We’ve completed step 1: 19d7cf6a-d252-4e7d-9d85-51f7249fd13e <-- printed by the external event handler as the aggregate is committed
We’ve got something to do: Need to do this (19d7cf6a-d252-4e7d-9d85-51f7249fd13e) <-- printed by the aggregate as it’s building state from history
We’ve completed step 2: 19d7cf6a-d252-4e7d-9d85-51f7249fd13e <-- printed by the external event handler as the aggregate is committed
We’ve got something to do: Need to do this (19d7cf6a-d252-4e7d-9d85-51f7249fd13e) <-- printed by the aggregate as it’s building state from history
We’ve completed step 3: 19d7cf6a-d252-4e7d-9d85-51f7249fd13e <-- printed by the external event handler as the aggregate is committed
We’ve got something to do: Need to do this (19d7cf6a-d252-4e7d-9d85-51f7249fd13e) <-- printed by the aggregate as it’s building state from history
We’ve completed a task: 19d7cf6a-d252-4e7d-9d85-51f7249fd13e <-- printed by the external event handler as the aggregate is committed

Hope that explains it.
Cheers,

Allard

Thanks for quick reply:)

I wasn’t sure what was best practice when it comes to event handling of the create event, so I might have put it on both places. I assume it has to be in the aggregate itself, in order to set the ID? It all makes more sense now:)

Think the final question then is: Is there a way to query all the events from the event store for a given aggregate? I assume the answer is YES, but HOW:)

Cheers,
Viggo

Actually, not all event stores have that ability. If you use the readEvents() of the EventStore, you’re guaranteed to get all events needed to reconstruct the aggregate. Since you could have snapshots, this might not be the entire stream.
If an EventStore implements EventStoreManagement, you can use the criteriaBuilder and visitEvents to read all events for a single aggregate. In future versions, I want to make this a bit easier.

Cheers,

Allard

I assume, based on the Axon documentation, that the MongoDB is the only event store which is recommended if I want a scalable DB in production.

MySQL scales just fine in terms of writes/second if you're willing to
resort to sharding which should be fairly straightforward for the
event store.

As for scaling to holding a large event store, I have yet to discover
how to handle that with a MySQL setup...