Old events resent on application start

We are prototyping an application with Spring Boot, Axon framework, and Axon server. (At the present state, all Axon configurations are at their default state - we haven’t implemented any configuration beans for this.)

In testing, I am sending a command that triggers an aggregate, and some additional events, internal Axon commands, projections, and external interactions.

All this seems to be working well enough, but if I stop the application and then restart it, I am seeing events being redelivered to all of the non-aggregate event listeners. @AllowReplay(false) does not prevent this. It seems likely that the Axon framework is not detecting the fact that the events have already been delivered, but this is causing the event handlers to repeat external interactions inappropriately.

Most likely this is a configuration error on my part, as I’m new to the Axon ecosystem. But I haven’t found anything obvious yet.

How do I prevent these events from being redelivered when the application is restarted, or redesign my events and commands to avoid this pitfall?

Thanks,
Hans Dykstra

Hello Hans,

This is a feature.
By default Axon Framework is using Tracking Event Processors to handle the events on the Query side.
Tracking Event Processors is using a token to track current positions of the event it is reading from the stream. This token is persisted in the SQL database.

If you are using JPA and H2 (in memory) database then this DB is dropped on each restart of the application. In this case, your tracking processor will start reading the event store again from the beginning (as your token is fresh/new, positioned at the head of the stream). Event store is located in the Axon Server data folder, you can consider deleting it if you want clean start in DEV/Local environments. Please note, that Axon Server has a DEV mode: https://docs.axoniq.io/reference-guide/operations-guide/setting-up-axon-server/development-mode

This is not related to @AllowReplay(false). Axon is using a separate ReplayToken for the replay logic, and @AllowReplay(false) makes sense only if you explicitly run reply https://docs.axoniq.io/reference-guide/configuring-infrastructure-components/event-processing/event-processors#replaying-events

Best,
Ivan

Thank you Ivan, that was very helpful.

We are using Postgres as our projection database, so it sounds like I need to configure the Axon server to use this as a persistent database for tracking then?

Thanks,
Hans Dykstra

Hello Hans,

indeed, you would need to do that. If you’re on Spring Boot, this is typically autoconfigured. If you’re not, you will need to configure the JpaTokenStore or JdbcTokenStore for your application. With that, on startup, the processor will resume where it left off in the previous run.

Kind regards,