Aggregate and Event snapshots

Hi,

I was reading up in the reference guide on snapshotting, and i noticed a distinction was being made between an Aggregate snapshot and a snapshot event.

https://docs.axoniq.io/reference-guide/configuring-infrastructure-components/command-processing/optimizing-aggregate-loading#initializing-an-aggregate-based-on-a-snapshot-event

following the code around snapshotting (SnapshotTriggerDefinition, SnapshotTrigger, EventStore) i found the creation of a GenericDomainEventMessage containing the aggregate. I suppose that is the snapshot event.

But the documentation also shows a custom snapshot event:

public class MyAggregate extends AbstractAnnotatedAggregateRoot {

// …

@EventHandler
protected void handleSomeStateChangeEvent(MyDomainEvent event) {
// …
}

@EventHandler
protected void applySnapshot(MySnapshotEvent event) {
// the snapshot event should contain all relevant state
this.someState = event.someState;
this.otherState = event.otherState;
}
}

Is the documentation outdated or do i miss something? In order to have a MySnapshotEvent would i need to implement a custom Snapshotter?

Regards,

Rolf

Hi Rolf,

we use the term “Snapshot Event” as a generic term for an Event that represents some state that replaces all prior events. An “Aggregate Snapshot” is basically the aggregate state contained as an event. In most cases, that’s exactly what you need in the snapshot. There may be edge cases where this is not ideal. In that case, you can create your own snapshotter (or override an existing one) to tweak how snapshots are made for a specific aggregate.

Hope this helps.
Cheers,

Allard

Hey Allard,

Thanks for your answer. Applying such a snapshot event and replacing all prior events is something i would have to build myself i assume?

Regards,

Rolf

Hi Rolf,

no, Axon will automatically detect available snapshots and use them instead of the events their state represents. If you don’t use the AggregateSnapshotter, then you will need to have an @EventSourcingHandler for the type of snapshotevent that you produce. Since the AggregateSnapshotter uses the aggregate itself as the snapshot, you don’t need to have an @EventSourcingHandler for it anymore.

Basically all you need to do, is define the “trigger” for creating snapshots.

Cheers,

How does the AggregateSnapshotter works when the aggregate changes?
By change, I mean fields, classes etc that aggregate is made of.

Any structural change of your aggregate could make snapshots unusable. Where possible, Axon will attempt to ignore these snapshots and either load the next one, or completely source the aggregates from its events.
Structurally, snapshots are much like regular events. That means you can upcast them and they can carry a Revision (which you can set by annotating your Aggregate with @Revision).

Cheers,

Hey Allard,

Producing a snapshot event is just applying a regular event with all fields needed to populate the aggregate?

How would the aggregate loader know to skip all previous events? Is there some metadata i can set? Do i need to archive / delete the previous events manually?

For example if i have an Insurance aggregate with an InsuranceRenewed event each year. I would like this event to contain all fields for my Insurance aggregate and “replace” all prior events (previous years). How would axon know to skip the events of the previous year(s)?

Thanks for your time!

Regards,

Rolf

Hi Rolf,

snapshot events aren’t created using the “apply” method that is used to apply events to the lifecycle of an Aggregate. It’s the Snapshotter that creates snapshots for an aggregate. The default is the AggregateSnapshotter, which basically takes the aggregate itself as the snapshot.

Typically all you need to worry about is when to create the snapshot. You define that by declaring a SnapshotTrigger. Axon provides a EventCountSnapshotTriggerDefinition that allows you to define a number of events that you consider the threshold to trigger a new snapshot.

If you use this mechanism for your snapshots, Axon will take care of loading them instead of your events. Nothing to worry about :wink:

Cheers,

Hi Allard,

Thank you for your reply. I was under the impression that there are two ways of creating snapshots: AggregateSnapshots (which you create through the Snapshotter) and SnapshotEvents. While it is clear to me how to snapshot the aggregate, it is not clear to me how you would produce a snapshot event.

For example, if i refer to your documentation:

A snapshot event is an event like any other. That means a snapshot event is handled just like any other domain event

@EventHandler

protected void applySnapshot(MySnapshotEvent event) {
// the snapshot event should contain all relevant state
this.someState = event.someState;
this.otherState = event.otherState;
}

In this case, how would MySnapshotEvent have been produced?

Sorry for rambling on about this, i understand the aggregate snapshot mechanism, just not the SnapshotEvent mechanism, if there is such a thing :slight_smile:

Kind regards,

Rolf

A snapshot is a regular event, but instead of the Aggregate creating an instance, it’s created by the Snapshotter. It’s stored in a different “stream” in the Event Store as well, so that the event store known which Snapshot replaces which Events from a stream.

Hope this clarifies it.
Cheers,