UnsupportedHandlerException: Unable to resolve parameter 1

I am new to CQRS, and I’m trying to complete a CRUD application. I have written create C, delete D, and returnall R, and now trying to update. I kept on getting the issue with the eventhandler. I hope someone can help me out.

DTO class

@Data
@Builder
public class AppDTO {

    private String name;
    private String description;

    @CreatedDate
    private Instant createdDate;
    @LastModifiedDate
    private Instant updatedDate;
    private AppStatus AppStatus;
}

Command class

@Data
@Builder
public class UpdateAppCommand {
    @TargetAggregateIdentifier
    private String appId;
    private String name;
    private String description;
    @CreatedDate
    private Instant createdDate;
    @LastModifiedDate
    private Instant updatedDate;
    private AppStatus AppStatus;
}

Service interface

AppDTO update(String id, AppDTO AppDTO);
void update(String id, AppUpdatedEvent AppUpdatedEvent);

controller class

@Autowired
IApp IApp;
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public AppDTO update( @PathVariable( value = "id") String id, @RequestBody @Valid AppDTO AppDTO){
    return IApp.update(id, AppDTO);
}

Service implementation class

@Override
public AppDTO update(String id, AppDTO AppDTO) {
    UpdateAppCommand UpdateAppCommand = UpdateAppCommand.builder()
            .appId(id)
            .name(AppDTO.getName())
            .description(AppDTO.getDescription())
            .build();
    return commandGateway.sendAndWait(UpdateAppCommand);
}

Updated event

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AppUpdatedEvent {
    private String appId;
    private String name;
    private String description;
    @CreatedDate
    private Instant createdDate;
    @LastModifiedDate
    private Instant updatedDate;
    private AppStatus AppStatus;
}

Command handler (aggregate)

@AggregateIdentifier
    private String appId;
    private String name;
    private String description;
    @CreatedDate
    private Instant createdDate;
    @LastModifiedDate
    private Instant updatedDate;
    private AppStatus AppStatus;

@CommandHandler
    public void update(UpdateAppCommand UpdateAppCommand) {
        //Perform predicate validations
        AppUpdatedEvent AppUpdatedEvent = new AppUpdatedEvent();
        BeanUtils.copyProperties(UpdateAppCommand, AppUpdatedEvent);
        AggregateLifecycle.apply(AppUpdatedEvent);
    }

@EventSourcingHandler
    public void on(AppUpdatedEvent AppUpdatedEvent) {
        this.appId = AppUpdatedEvent.getappId();
        this.name = AppUpdatedEvent.getName();
        this.description = AppUpdatedEvent.getDescription();
        this.createdDate = AppUpdatedEvent.getCreatedDate();
        this.updatedDate = AppUpdatedEvent.getUpdatedDate();
        this.AppStatus = AppStatus.UPDATED;
    }
Event to database
@EventHandler
    public void on( String id, AppUpdatedEvent AppUpdatedEvent ) {
        if (!appRepository.existsByAppId(id)){
            throw new NoSuchElementException("The account does not exist");
        }
        App App = appRepository.findByAppId(id);
        App.setAppId(AppUpdatedEvent.getAppId());
        App.setName(AppUpdatedEvent.getName());
        App.setDescription(AppUpdatedEvent.getDescription());
        App.setAppStatus(AppStatus.UPDATED);
        appRepository.save(App);
    }

I kept on getting this error

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-04-16 12:47:22.900 ERROR 15706 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.context.ApplicationContextException: Failed to start bean 'org.axonframework.spring.config.AxonConfiguration'; nested exception is org.axonframework.lifecycle.LifecycleHandlerInvocationException: One of the start handlers in phase [null] failed with the following exception:
	at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:181) ~[spring-context-5.3.18.jar:5.3.18]
	at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:54) ~[spring-context-5.3.18.jar:5.3.18]
	at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:356) ~[spring-context-5.3.18.jar:5.3.18]
	at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na]
	at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:155) ~[spring-context-5.3.18.jar:5.3.18]
	at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:123) ~[spring-context-5.3.18.jar:5.3.18]
	at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:935) ~[spring-context-5.3.18.jar:5.3.18]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586) ~[spring-context-5.3.18.jar:5.3.18]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.6.6.jar:2.6.6]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740) ~[spring-boot-2.6.6.jar:2.6.6]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415) ~[spring-boot-2.6.6.jar:2.6.6]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) ~[spring-boot-2.6.6.jar:2.6.6]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) ~[spring-boot-2.6.6.jar:2.6.6]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) ~[spring-boot-2.6.6.jar:2.6.6]
	at io.atp.Appservice.AppserviceApplication.main(AppserviceApplication.java:14) ~[classes/:na]
Caused by: org.axonframework.lifecycle.LifecycleHandlerInvocationException: One of the start handlers in phase [null] failed with the following exception:
	at org.axonframework.config.DefaultConfigurer.lambda$invokeStartHandlers$35(DefaultConfigurer.java:693) ~[axon-configuration-4.5.9.jar:4.5.9]
	at org.axonframework.config.DefaultConfigurer.invokeLifecycleHandlers(DefaultConfigurer.java:744) ~[axon-configuration-4.5.9.jar:4.5.9]
	at org.axonframework.config.DefaultConfigurer.invokeStartHandlers(DefaultConfigurer.java:687) ~[axon-configuration-4.5.9.jar:4.5.9]
	at org.axonframework.config.DefaultConfigurer$ConfigurationImpl.start(DefaultConfigurer.java:811) ~[axon-configuration-4.5.9.jar:4.5.9]
	at org.axonframework.spring.config.AxonConfiguration.start(AxonConfiguration.java:199) ~[axon-spring-4.5.9.jar:4.5.9]
	at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:178) ~[spring-context-5.3.18.jar:5.3.18]
	... 14 common frames omitted
Caused by: java.util.concurrent.ExecutionException: org.axonframework.messaging.annotation.UnsupportedHandlerException: Unable to resolve parameter 1 (AppUpdatedEvent) in handler public void io.atp.Appservice.command.api.events.AppEventHandlers.on(java.lang.String,io.atp.Appservice.command.api.events.AppUpdatedEvent).
	at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:396) ~[na:na]
	at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2096) ~[na:na]
	at org.axonframework.config.DefaultConfigurer.invokeLifecycleHandlers(DefaultConfigurer.java:742) ~[axon-configuration-4.5.9.jar:4.5.9]
	... 18 common frames omitted
Caused by: org.axonframework.messaging.annotation.UnsupportedHandlerException: Unable to resolve parameter 1 (AppUpdatedEvent) in handler public void io.atp.Appservice.command.api.events.AppEventHandlers.on(java.lang.String,io.atp.Appservice.command.api.events.AppUpdatedEvent).
	at org.axonframework.messaging.annotation.AnnotatedMessageHandlingMember.<init>(AnnotatedMessageHandlingMember.java:76) ~[axon-messaging-4.5.9.jar:4.5.9]
	at org.axonframework.messaging.annotation.AnnotatedMessageHandlingMemberDefinition.lambda$createHandler$0(AnnotatedMessageHandlingMemberDefinition.java:51) ~[axon-messaging-4.5.9.jar:4.5.9]
	at java.base/java.util.Optional.map(Optional.java:260) ~[na:na]
	at org.axonframework.messaging.annotation.AnnotatedMessageHandlingMemberDefinition.createHandler(AnnotatedMessageHandlingMemberDefinition.java:48) ~[axon-messaging-4.5.9.jar:4.5.9]
	at org.axonframework.messaging.annotation.MultiHandlerDefinition.createHandler(MultiHandlerDefinition.java:182) ~[axon-messaging-4.5.9.jar:4.5.9]
	at org.axonframework.messaging.annotation.AnnotatedHandlerInspector.initializeMessageHandlers(AnnotatedHandlerInspector.java:203) ~[axon-messaging-4.5.9.jar:4.5.9]
	at org.axonframework.messaging.annotation.AnnotatedHandlerInspector.initialize(AnnotatedHandlerInspector.java:194) ~[axon-messaging-4.5.9.jar:4.5.9]
	at org.axonframework.messaging.annotation.AnnotatedHandlerInspector.createInspector(AnnotatedHandlerInspector.java:150) ~[axon-messaging-4.5.9.jar:4.5.9]
	at org.axonframework.messaging.annotation.AnnotatedHandlerInspector.inspectType(AnnotatedHandlerInspector.java:135) ~[axon-messaging-4.5.9.jar:4.5.9]
	at org.axonframework.messaging.annotation.AnnotatedHandlerInspector.inspectType(AnnotatedHandlerInspector.java:117) ~[axon-messaging-4.5.9.jar:4.5.9]
	at org.axonframework.eventhandling.AnnotationEventHandlerAdapter.<init>(AnnotationEventHandlerAdapter.java:81) ~[axon-messaging-4.5.9.jar:4.5.9]
	at org.axonframework.eventhandling.SimpleEventHandlerInvoker$Builder.wrapEventMessageHandler(SimpleEventHandlerInvoker.java:304) ~[axon-messaging-4.5.9.jar:4.5.9]
	at org.axonframework.eventhandling.SimpleEventHandlerInvoker.lambda$new$0(SimpleEventHandlerInvoker.java:66) ~[axon-messaging-4.5.9.jar:4.5.9]
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) ~[na:na]
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682) ~[na:na]
	at org.axonframework.eventhandling.SimpleEventHandlerInvoker.<init>(SimpleEventHandlerInvoker.java:67) ~[axon-messaging-4.5.9.jar:4.5.9]
	at org.axonframework.eventhandling.SimpleEventHandlerInvoker$Builder.build(SimpleEventHandlerInvoker.java:286) ~[axon-messaging-4.5.9.jar:4.5.9]
	at org.axonframework.config.EventProcessingModule.lambda$null$33(EventProcessingModule.java:266) ~[axon-configuration-4.5.9.jar:4.5.9]
	at org.axonframework.config.EventProcessingModule.lambda$buildEventProcessor$39(EventProcessingModule.java:307) ~[axon-configuration-4.5.9.jar:4.5.9]
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) ~[na:na]
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682) ~[na:na]
	at org.axonframework.config.EventProcessingModule.buildEventProcessor(EventProcessingModule.java:308) ~[axon-configuration-4.5.9.jar:4.5.9]
	at org.axonframework.config.EventProcessingModule.lambda$null$22(EventProcessingModule.java:191) ~[axon-configuration-4.5.9.jar:4.5.9]
	at org.axonframework.config.Component.get(Component.java:84) ~[axon-configuration-4.5.9.jar:4.5.9]
	at java.base/java.util.HashMap$Values.forEach(HashMap.java:1065) ~[na:na]
	at org.axonframework.config.EventProcessingModule.lambda$initializeProcessors$24(EventProcessingModule.java:210) ~[axon-configuration-4.5.9.jar:4.5.9]
	at org.axonframework.config.Configuration.lambda$onStart$9(Configuration.java:394) ~[axon-configuration-4.5.9.jar:4.5.9]
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) ~[na:na]
	at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:992) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
	at java.base/java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:662) ~[na:na]
	at org.axonframework.config.DefaultConfigurer.invokeLifecycleHandlers(DefaultConfigurer.java:740) ~[axon-configuration-4.5.9.jar:4.5.9]
	... 18 common frames omitted

I think the problem is here:

    public void on( String id, AppUpdatedEvent AppUpdatedEvent ) {

Axon does not know what to do because you have a String as a parameter. What should it resolve the string to?

Unable to resolve parameter 1 (AppUpdatedEvent) in handler public void io.atp.Appservice.command.api.events.AppEventHandlers.on(java.lang.String,io.atp.Appservice.command.api.events.AppUpdatedEvent)

Try to get rid of the string parameter and extract the ID directly from the event.

Regards,

1 Like

Hi @ken4ward ,

@vab2048 is right, the signature of a message handler in Axon always starts with the message (command, event or query).
When moving from CRUD to CQRS it is important to know that CQRS separates the writes and the reads. A UpdateAppCommand is not something you would see in CQRS. A command is more behavior-driven like RegisterAcount. The event that could be applied AccountRegistered.

Kind regards,

Yvonne