Using Axon framework 4.2 and axon server 4.1.1 (axonserver probably not relevant here) and using Axon spring boot starter, I am having the following issue:
My application wil not start, because Axon cannot resolve a parameter (spring bean injection) from one of the command handlers of aggregate “Klas”.
This is the aggregate: (simplified)
`
@Aggregate
public class Klas {
@AggregateIdentifier
private KlasId klasId;
private Klas() {}
Klas(KlasGegevens klasGegevens) {
apply(new KlasAangemaakt(klasId(klasGegevens),klasGegevens));
}
@CommandHandler
public AlbumId cmd(VoegAlbumToe cmd, @Qualifier(“albumIdGenerator”) AlbumIdGenerator albumIdGenerator)
throws Exception {
AlbumId albumId = albumIdGenerator.generate();
(…)
return albumId;
}
(…)
}
`
The AlbumIdGenerator is just a simple spring bean with a @Service annotation:
`
@Service(“albumIdGenerator”)
public class AlbumIdGenerator {
public AlbumIdGenerator() {}
public AlbumId createAlbumId() {
return AlbumId.generate();
}
}
`
Now, this problem arises from the fact that I define my own EventSourcingRepository for Aggregate 'Klas":
(sorry, I am mixing Java and Kotlin in my project, but that does not seem to be the problem)
`
@Configuration
open class KlasRepositoryConfig {
@Bean
open fun klasRepository(snapshotTriggerDefinition: SnapshotTriggerDefinition, eventStore: EventStore): EventSourcingRepository {
return EventSourcingRepository.builder(Klas::class.java)
.snapshotTriggerDefinition(snapshotTriggerDefinition)
.eventStore(eventStore)
.build()
}
}
`
The moment this EventSourcing klas repository (tries to be) instantiated, I get the following error:
`
java.lang.IllegalStateException: Failed to load ApplicationContext
(…)Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘klasFactory’: Unsatisfied dependency expressed through field ‘repository’; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘klasRepository’ defined in class path resource [be/triptrapschool/foto/domain/klas/KlasRepositoryConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.axonframework.eventsourcing.EventSourcingRepository]: Factory method ‘klasRepository’ threw exception; nested exception is org.axonframework.messaging.annotation.UnsupportedHandlerException: Unable to resolve parameter 1 (AlbumIdGenerator) in handler public be.triptrapschool.foto.domain.album.AlbumId be.triptrapschool.foto.domain.klas.Klas.cmd(be.triptrapschool.foto.domain.klas.VoegAlbumToe,be.triptrapschool.foto.domain.album.AlbumIdGenerator) throws java.lang.Exception.
`
So Axon cannot resolve the “AlbumIdGenerator” parameter in the command handling method of Klas.
Why?
Axon tries to resolve the “AlbumIdGenerator” parameter using a number of parameter resolvers, defined in an (Axon) “MultiParameterResolverFactory”. This resolver factory contains 11 specific resolver factories. However, it needs a Parameter resolver factory which will lookup the “AlbumIdGenerator” in the spring context. This resolver factory is called the ‘SpringBeanResolverFactory’. The SpringBeanResolverFactory is missing in the list of 11 factories at the time the KlasRepository is instantiated.
The ‘SpringBeanResolverFactory’ is added later on in the startup process of Spring, by axons’s ‘AnnotationCommandHandlerBeanPostProcessor’
My question:
- How can I create the KlasRepository later on, AFTER the AnnotationCommandHandlerBeanPostProcessor has been executed? (so that this problem is avoided)
- Do you have a better suggestion to my setup, to resolve this issue?
- I need an instance of the klas EventSourcingRepository, because I am using a Factory to create the Klas objects. Is there another way of accessing the klas EventSourcingRepository, without defining it as a bean myself? (have it auto-created by axon at the right time)
I thank you