Axon event store - where exactly is it stored when Axon server is being used.

Hello,
Firstly I am a newbie to microservices and Axon so pardon me for the basic question. I understand that Axon provides by default its own event store. I came across below code example that implements Axon with CQRS-ES using Bank Account as example.

https://github.com/dashsaurabh/event-sourcing-cqrs-axon-spring-boot/tree/master/src/main/java/com/progressivecoder/es/eventsourcingcqrsaxonspringboot/aggregates

The project maven excludes Axon server connector and is using H2 in memory database to store Account details.
When I run the code I am able to see the Account details in H2 using H2 console however the Events table is missing. So I am trying to understand where exactly the event is stored.

The attached document has details about my question.

Thanks,
Amith

Axon.docx (142 KB)

Hello Amit,

I am still trying to get somebody to pick your question up. However we are in the midst of a new release (4.3) and our developers are busy. We will try to give you an answer no later than Monday, okay?

Henk

Hello Amit,

In this particular example, you are excluding Axon Connector totally. This means that your application is not going to use (and connect) Axon Server as an Event Store and message broker.
It is going to fall back to SQL (H2 in your case) database as an Event Store for you because you have spring-boot-starter-data-jpa included in the POM.

To clarify the answer, you should get familiar with the event sourcing pattern and CQRS pattern first.

Your aggregate is the most important component. It is responsible for handling commands and publishing events as information that the state of your aggregate has been changed.
By using event sourcing your aggregate is saved as a series of events in DOMAIN_EVENT_ENTRY table (event store).
This way of saving the state is very powerful as you gain a 100% audit and you keep all the history, but it is not very convenient for querying and reading. This is where CQRS pattern kicks in.
Your aggregate lives on the Comand side (CQRS), but there is AccountQueryEntityManager.java component that lives on the Query side (CQRS). This Query component is subscribed to events published from your aggregate/command component and it is projecting/mapping these events in the SQL table by creating and updating the Account Query entity. This projection is more optimal for reading, which you are already doing by exposing the REST endpoint on top of the repository.

Best,
Ivan

Hello Ivan,

Thanks for the very detailed answer!! I figured out that when I
include Axon connector then the events are stored under a data folder
where Axon server is installed.
This means that Axon is maintaining its own event store. However I
could not understand one point as mentioned below....
I run the code sample with Axon connector included and create I
several Accounts. The events get stored in Axon's default event store.
The Accounts are stored in H2 as expected. I stop my application. Then
I restart my application.
Now this code flows through AccountQueryEntityManager.java component
where there is one method called persistAccount. All the events in the
event store are read one by one and the persistAccount() method is
called to save Account details.
Why is this save to H2 happening upon application start each time.
Looks like Axon framework is writing to H2 and re-adding the same rows
to H2.
Is this the default behaviour? Is there a configuration to stop the
code from saving already saved data?

Thanks,
Amith

Once you include Axon connector you will be using Axon Server as an event store and as a message (command, event, query) broker.
It is correct, the events will be stored under the data folder now. Please mind, that you are using Axon Server as a broker now as well. This enables you to scale out your application to more instances, and messages will be correctly distributed between them. You would be able to distribute your messages(events, commands, queries) to other applications that are interested as well. No need for RabbitMQ (to distribute events), SpringCloud (to distribute commands) anymore. Everything just works out of the box for you.

You still use SQL database (or some NoSQL) to store your projections/views. This is the query side where you have Event handlers that are subscribed to events from event store.
By default, your application is using tracking event processors.

Tracking event processors, unlike subscribing ones (the second type of processors), need a token store to store their progress in. Each message a tracking processor receives through its event stream/store is accompanied by a token. This token allows the processor to reopen the stream at any later point, picking up where it left off with the last Event.

Minding your configuration with JPA, this token is saved in SQL db table (it is not stored in axon server). As you are using in memory H2 databse, by restarting your application (probably with create-drop) you are wiping out your token, and once the application is started it starts reading all events from the EventStore to recreate your projection. This is normal and expected behavior! If you want a clean (create-drop) start, I would suggest deleting your data folder on Axon Server as well (on each restart) to support create-drop all the way. This process is only valid in DEV environments, you should not delete your event store in higher environments.

Best,
Ivan