Force creation of snapshots


A question on how to force axon to create snapshots for all my aggregates. I have created a SnapshotTriggerDefinition which creates a snapshot after 50 events. This definition is only triggered when a new event comes in. That’s when the eventHandled method gets called and starts to count the number of events. We are expecting a big load in the next weeks which will affect all our aggregates. Is it possible to create a snaphot of each aggregate prior to this load, in some sort of batch? This will speed up loading the aggregates once this big load starts.

Thanks, Norbert

1 Like

Hi @Norbert_Terhorst,

You can create a specific command that will trigger a snapshot of an Aggregate.
One of our colleagues already answered something similar on Stackoverflow and this is why I am linking it here instead of copying the solution.

Hope it helps!


Hi Lucas,

That’s it! Thanks

Hi @lfgcampos !

I’m trying the approach described in the SO answer you pointed out and it does create a snapshot, but also throws an NPE at some point. I reckon (but I’m not 100% sure) this happens because the aggregate is not hydrates at the moment the command is processed. For what I can see, the issue might at some point the logic picks the ID of the aggregate as null, and that ends up causing the NPE.

This is the stack trace I get (we are using axon

AbstractUnitOfWork : Rolling back Unit Of null
	at java.base/java.util.concurrent.ConcurrentHashMap.get(
	at org.axonframework.common.lock.PessimisticLockFactory.lockFor(
	at org.axonframework.common.lock.PessimisticLockFactory.obtainLock(
	at org.axonframework.modelling.command.LockingRepository.doCreateNew(
	at org.axonframework.modelling.command.LockingRepository.doCreateNew(
	at org.axonframework.modelling.command.AbstractRepository.newInstance(
	at org.axonframework.modelling.command.AggregateAnnotationCommandHandler$AggregateConstructorCommandHandler.handle(
	at org.axonframework.modelling.command.AggregateAnnotationCommandHandler$AggregateConstructorCommandHandler.handle(
	at org.axonframework.modelling.command.AggregateAnnotationCommandHandler.handle(
	at org.axonframework.modelling.command.AggregateAnnotationCommandHandler.handle(
	at org.axonframework.messaging.DefaultInterceptorChain.proceed(
	at org.axonframework.messaging.interceptors.CorrelationDataInterceptor.handle(
	at org.axonframework.messaging.DefaultInterceptorChain.proceed(

The code I run is the same as on the SO answer:

snapshotter.scheduleSnapshot(this.getClass(), cmd.getId());

The issue seems to come from CachingEventSourcingRepository<T>doCreateNewForLock(), as aggregate.identifierAsString()) returns null.

protected EventSourcedAggregate<T> doCreateNewForLock(Callable<T> factoryMethod) throws Exception {
    EventSourcedAggregate<T> aggregate = super.doCreateNewForLock(factoryMethod);
    CurrentUnitOfWork.get().onRollback(u -> cache.remove(aggregate.identifierAsString()));
    cache.put(aggregate.identifierAsString(), new AggregateCacheEntry<>(aggregate));
    return aggregate;

Any ideas or gut feeling of what might be the cause of this? Any tips on how to debug these issues is welcomed too.

Hi @augusto , I have a somewhat working example on our code-samples repo as a PR still.

But looking at what you shared, I would also like to see the snippet of your configuration and also the Aggregate itself. That would help.
As a final remark, can you test with latest AF, which is 4.5 btw? I have a hunch that this problem is not present anymore and could be something we already fixed in the past.


Hi Lucas! And thanks for the reply!

I spent a bit more time looking at this and it was a ‘user’ problem. I ‘cloned’ a command handler that was applied to a constructor in the same class rather than a method, so Axon was creating an empty instance, which failed to be persisted in the cache as it didn’t have an aggregate id. The snapshot was successful as it applied to a different instance of the same aggregate.

1 Like

Hi @augusto, thanks for getting back and letting us know the problem is fixed on your end!

If you need any further help, let us know.