I am facing issues with @EventHandler mechanism (most likely due to a mistake on my part I assume).
I am using Axon 3.0.2 and I committed my code on https://github.com/teivah/testaxon.
Basically what I’m trying to achieve is from com.test.axonpoc.AxonpocTest to send two commands: FPCreateCommand and FPEnableCommand.
There’s a handler on both (FPCommandHandler) but the second one invokes FP.enable(boolean). This second method does an apply to publish the event FPEnabledEvent. This is where the issue arise.
I would like basically to have two different handler types on the FPEnabledEvent event: an @EventSourcingHandler (in FP) and one or several @EventHandler (in FPView).
What I can see in the logs in that the @EventSourcingHandler method is correctly invoked. Nonetheless the @EventHandler method is never called.
I saw in another thead that Allard Buijze said: “When the command handler completes succesfully, the event is published to all @EventHandler components in the application, via the Event Bus.”.
Does it mean then I miss something in my @CommandHandler method? I cannot tell by myself…
Looks like you registered two spring beans for EventBus. In Axon 3 the EventStore is also your event bus. So when the aggregate applies the event it will later get published by the EventStore. However, your application is registering event handlers to the SimpleEventBus you’ve registered as EventBus so they never get the events.
In short, get rid of the @Bean annotated getEventBus method.
engine = new InMemoryEventStorageEngine();
eventStore = new EmbeddedEventStore(engine);
repository = new CachingEventSourcingRepository<>(new GenericAggregateFactory<>(FP.class), eventStore, NoCache.INSTANCE);
commandBus = new SimpleCommandBus();
EventHandlingConfiguration ehConfiguration = new EventHandlingConfiguration().usingTrackingProcessors();
I believe I missed to call the registerEventHandler() method.
So I changed to:
`
engine = new InMemoryEventStorageEngine();
eventStore = new EmbeddedEventStore(engine);
repository = new CachingEventSourcingRepository<>(new GenericAggregateFactory<>(FP.class), eventStore, NoCache.INSTANCE);
commandBus = new SimpleCommandBus();
EventHandlingConfiguration ehConfiguration = new EventHandlingConfiguration().registerEventHandler(c -> new FPView());
The problem is that you create an instance of EmbeddedEventStore, but use configurer->configureEmbeddedEventStore(…). The latter will create another instance, meaning you have two.
Remove the creation of the Event Store, and register your command handler as follows:
.registerCommandHandler(c -> new FPCommandHandler(repository, c.eventStore()))
EventHandlingConfiguration ehConfiguration = new EventHandlingConfiguration()
.registerEventHandler(c -> new FPView());
configuration = DefaultConfigurer.defaultConfiguration().registerModule(ehConfiguration)
.registerCommandHandler(
c -> new FPCommandHandler((repository = new CachingEventSourcingRepository<>(
new GenericAggregateFactory<>(FP.class), c.eventStore(), NoCache.INSTANCE)),
c.eventStore()))
.configureCommandBus(c -> commandBus).configureEmbeddedEventStore(c -> engine)
.configureAggregate(FP.class).buildConfiguration();
`
I did the change but because the repository needs an event store as well, I instantiated my repository variable within the registerCommandHandler.
Did I miss something?
Try to instantiate as little components inside the configuration as possible. If you need a repository, you can get one by doing: configuration.repository(FP.class). The line “.configureAggregate(…)” will ensure a suitable repository is available.
Ok I just progressed! I saw that if I remove the two last lines concerning the uow I got my event!
At runtime though, I am facing this exception: java.lang.IllegalStateException: No UnitOfWork is currently started for this thread.
There is nothing wrong with starting your own unit of work, but it’s hardly ever really necessary.
Where do you get the exception? The Command Bus will create and manage a Unit of Work when you send a command.
Note that you need to commit() your Unit of Work as well. Events aren’t dispatched until it is committed.
The last two lines of code are a query, actually. You shouldn’t use your command model for that.
If you want to test this, you should do something that will behave differently when the FP is enabled or disabled. That’s how you can verify the flag works. Or otherwise, verify that an FPEnabledEvent has passed by.
But if you really must load an aggregate like this, you will need to have an active Unit of Work.
Another thing closely related to my original question. When I use the FixtureConfiguration object, the @EventSourcingHandler method is triggered but not the @EventHandler one.
I tried as the doc says to use the registerInjectableResource() method but nothing changed. I am not sure actually what should be passed to this method (I tried both the object exposing the @EventHandler method and the java.lang.Method object itself).
Is there any trick I missed? I created the fixture this way:
`
fixture = new AggregateTestFixture<>(FlightObject.class);
flightCommandHandler.setRepository(fixture.getRepository());
flightCommandHandler.setEventBus(fixture.getEventBus());
fixture.registerAnnotatedCommandHandler(flightCommandHandler);
fixture.registerInjectableResource(appliAView);
The fixture is meant to test your command model, not the query models. So any event handlers on external components (any component other than the event sourced aggregate) is not invoked.