Querying the aggregate's updated state

Hi,

Short Story:
I want to get the current state of an Aggregate entry (taking into consideration all events and snapshots that has happened to it) without tracking the changes to that Aggregate via @Entity (i.e. without tracking the changes to that aggregate via sql update statements).

Long Story:
I am new to Axon and my experience with CQRS has only been a few days of using Lagom. So I may be off with my understanding of some of the concepts. But here’s my understanding

An Aggregate can accept Commands and those Commands basically represent what you can do with that Aggregate. And Events are records/logs of what happened to that Aggregate. And when persisting the Aggregate into the database, instead of persisting the changes as update statements into the database, Events are the ones that are persisted instead. That way, you can rebuild the state of the Aggregate by ‘replaying’ the events.

So for example, let’s say we have a InventoryItem entity (with an id, name, quantity), if the following things are to happen

  1. Added 10 new TShirts InventoryItem
  2. Update quantity to 8
  3. Update quantity to 3
  4. Update quantity to 13
  5. Update name to T-Shirts

In a traditional database approach, this would look like this

  1. insert into inventory_item (id, name, quantity) values (1, “TShirts”, 10);

  2. update inventory_item set quantity = 8 where id = 1;

  3. update inventory_item set quantity = 3 where id = 1;

  4. update inventory_item set quantity = 13 where id = 1;

  5. update inventory_item set name = “T-Shirts” where id = 1;

And then if you want to query the current state of that item, you would do

select id, name, quantity from inventory_item where id = 1;

Now in a CQRS system, it would look something like this instead

  1. AddNewInventoryItem - name = TShirts, quantity = 10

  2. UpdateQuantityOfInventoryItem - quantity = 8

  3. UpdateQuantityOfInventoryItem - quantity = 3

  4. UpdateQuantityOfInventoryItem - quantity = 13

  5. UpdateNameOfInventoryItem - name = “T-Shirts”

And then if you want to query the current state of that item, you would replay all those events which eventually result to an InventoryItem of name “T-Shirts” and quantity 13.

In Axon, I believe Events are stored in an EventStore. And this can be in memory, or backed by RDBMs or Mongo or whatever.

However, I cant seem to figure out how to query the current state of an Aggregate (through “event replaying”).

Most examples, make the aggregate @Entity which means not only are Events being stored, but changes to the Aggregate are also being tracked via sql update statements.

Am I missing something? Can anybody recommend a documentation page / sample code base where I can get the current state of an aggregate without tracking the changes to that Aggregate with @Entity (or sql update statements) ?

Thanks,
Franz

Hello Franz,
Simply put, the aggregate takes commands as input and produces events as output. It’s not really meant for querying. This is why you have, say, an event listener which will handle events and update the query model which is what you will actually use.

When eventsourcing is used then you should have a readmodel. Depending on how frequently the orders are created you should in the readmodel only do inserts.

Insert record items 20
Insert record items -2
Insert record items -5

Using a batch you can aggregate the record’s into the actual state. This approach is used when you have a high frequency of orders. This way you are not causing locks. Eventually consistency means that some of the orders will be rejected because of out of stock.

The other approach is that you enrich the events for every item to including the aggregated amount. In the readmodel you just persist the aggregated amount.

To build the aggregated all the events are replayed. So you have everything to enrich the events. Here the usage of snapshots may help you to have better performance.

Normally you are not reading from eventstore and presenting it in UI. Therefore is the readmodel meant.

Hi Franz, Brian and Marinko,

Brian and Marinko have already been pointing you in the right direction Franz.
Typically, if you’re doing Event Sourcing with an Axon application, that means you are separating the concerns of handling commands / decision making from answering queries. This is where CQRS comes around the corner.

The Command Model in such a situation is not meant to store all the state you’d need when querying.

It is only meant to keep the state it needs to make the decisions on handling an incoming command.

The Query Model on the other hand will listen to all the events which are relevant for that given model, and instantiate/update a view model based on that.

This model is what you can then query (for example by using the QueryBus).

That’s my 2 cents.

Cheers,
Steven