Hello,
We’re trying to use
@Bean
public Cache someAggregateCache() {
return new WeakReferenceCache();
}
for an aggregate. The cache is set by
@Aggregate(cache = "someAggregateCache")
We are using custom runtimeexceptions to exit command handlers in certain cases. This causes a rollback and pops out as a nullpointer exception on the WeakReferenceCache.
We tried circumvent the rollback from happening by doing:
@Bean
public CommandBus commandBus(TransactionManager transactionManager,
GlobalMetricRegistry metricRegistry,
SpanFactory spanFactory) {
return SimpleCommandBus.builder()
.transactionManager(transactionManager)
.messageMonitor(metricRegistry.registerCommandBus("commandBus"))
.spanFactory(spanFactory)
.rollbackConfiguration(new CommandRollbackConfiguration())
.build();
}
@Bean
public ConfigurerModule commandBusCorrelationConfigurerModule() {
return configurer -> configurer.onInitialize(
config -> config.commandBus().registerHandlerInterceptor(
new CorrelationDataInterceptor<>(config.correlationDataProviders())
)
);
}
@Bean
public CommandGateway commandGateway(CommandBus commandBus) {
return DefaultCommandGateway.builder().commandBus(commandBus).build();
}
public class CommandRollbackConfiguration implements RollbackConfiguration {
@Override
public boolean rollBackOn(Throwable throwable) {
return !(throwable instanceof CustomRuntimeException);
}
}
but the behaviour didn’t change. We added debug logging to rollBackOn() to ensure it’s being run which it did.
Is something wrong with the setup? How can we use a cache while still be able to exit command handlers at will?
We are using:
Java 11
Spring Boot 2.7.18
Axon 4.6.8
(We are updating the versions in the future, but as of now still stuck with these.)
P.S. as an added note, we noticed that this happened even if command handlers were exited without throwing or applying events – basically doing nothing. I assume not creating an event triggers a rollback either way by default?
Here is the trace for the nullpointer:
java.lang.NullPointerException: null
at java.base/java.util.concurrent.ConcurrentHashMap.replaceNode(ConcurrentHashMap.java:1111)
at java.base/java.util.concurrent.ConcurrentHashMap.remove(ConcurrentHashMap.java:1102)
at org.axonframework.common.caching.WeakReferenceCache.remove(WeakReferenceCache.java:133)
at org.axonframework.eventsourcing.CachingEventSourcingRepository.lambda$doSaveWithLock$1(CachingEventSourcingRepository.java:87)
at org.axonframework.messaging.unitofwork.MessageProcessingContext.notifyHandlers(MessageProcessingContext.java:72)
at org.axonframework.messaging.unitofwork.DefaultUnitOfWork.notifyHandlers(DefaultUnitOfWork.java:109)
at org.axonframework.messaging.unitofwork.AbstractUnitOfWork.changePhase(AbstractUnitOfWork.java:236)
at org.axonframework.messaging.unitofwork.AbstractUnitOfWork.commitAsRoot(AbstractUnitOfWork.java:90)
at org.axonframework.messaging.unitofwork.AbstractUnitOfWork.commit(AbstractUnitOfWork.java:75)
at org.axonframework.messaging.unitofwork.DefaultUnitOfWork.executeWithResult(DefaultUnitOfWork.java:95)
at org.axonframework.commandhandling.SimpleCommandBus.lambda$handle$4(SimpleCommandBus.java:201)
at org.axonframework.tracing.Span.runSupplier(Span.java:163)
at org.axonframework.commandhandling.SimpleCommandBus.handle(SimpleCommandBus.java:192)
at org.axonframework.commandhandling.SimpleCommandBus.doDispatch(SimpleCommandBus.java:165)
at org.axonframework.commandhandling.SimpleCommandBus.lambda$dispatch$2(SimpleCommandBus.java:131)
at org.axonframework.tracing.Span.run(Span.java:101)
at org.axonframework.commandhandling.SimpleCommandBus.dispatch(SimpleCommandBus.java:125)
at org.axonframework.commandhandling.gateway.AbstractCommandGateway.send(AbstractCommandGateway.java:76)
at org.axonframework.commandhandling.gateway.DefaultCommandGateway.send(DefaultCommandGateway.java:83)
at org.axonframework.commandhandling.gateway.DefaultCommandGateway.send(DefaultCommandGateway.java:138)