Event handler issue

Hello all,

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…

Thanks for your help guys!

Hi,

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.

Best,
Rene

Thanks for the fast reply Rene.

I updated the @Before method like this:

`

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();

configuration = DefaultConfigurer.defaultConfiguration().registerModule(ehConfiguration)
.registerCommandHandler(c -> new FPCommandHandler(repository, eventStore))
.configureCommandBus(c -> commandBus)
.configureEmbeddedEventStore(c -> engine).configureAggregate(FP.class).buildConfiguration();

configuration.start();

`

But I still can’t get catch any events with @EventHandler. Looks like the FPView is not registered or something like that…

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());

configuration = DefaultConfigurer.defaultConfiguration().registerModule(ehConfiguration)
.registerCommandHandler(c -> new FPCommandHandler(repository, eventStore))
.configureCommandBus(c -> commandBus).configureEmbeddedEventStore(c -> engine)
.configureAggregate(FP.class).buildConfiguration();

`

It is perhaps better than before, but still not working.

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()))

That should do the trick.

Thanks Allard for the reply.

I assume I’m getting closer but still no event:

`

engine = new InMemoryEventStorageEngine();

commandBus = new SimpleCommandBus();

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?

Thank you

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.

Did you do a configuration.start() ?

Cheers,

Allard

Yes I did use a configuration.start().

Ok noted, I simplified my setup. The full setup method looks like this:

`

//Init
engine = new InMemoryEventStorageEngine();
eventStore = new EmbeddedEventStore(engine);
commandBus = new SimpleCommandBus();

//Configuration
EventHandlingConfiguration ehConfiguration = new EventHandlingConfiguration()
.registerEventHandler(c -> new FPView());

configuration = DefaultConfigurer.defaultConfiguration()
.configureEventStore(c -> eventStore)
.configureAggregate(AggregateConfigurer.defaultConfiguration(FP.class))
.configureCommandBus(c -> commandBus)
.registerModule(ehConfiguration)
.registerCommandHandler(
c -> new FPCommandHandler(
c.repository(FP.class),
eventStore)
)
.buildConfiguration();

configuration.start();

//Retrieve repository and commandGateway objects
repository = configuration.repository(FP.class);
commandGateway = configuration.commandGateway();

uow = new DefaultUnitOfWork<>(null);
uow.start();

`

I reuse the eventStore object because I wanted to initialize it explicitly as an embedded one.

Nonetheless, still no events…

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.

What’s wrong with starting its own uow?

Thanks

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.

Cheers,

Allard

Thanks for the information. I checked as well in the documentation, and for my very use case indeed I do not need to manage the uow.

I removed every usage to the uow, but I am facing still the error in my test case, line 3:

`

commandGateway.sendAndWait(new FPCreateCommand(FPID1));
commandGateway.sendAndWait(new FPEnableCommand(FPID1, true));
Aggregate agg = repository.load(FPID1); //right here
assertEquals(true, agg.invoke(FP::isEnabled));

`

The repository was retrieved using configuration.repository(myClass).

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.

Cheers,

Allard

Okay understood. It is now working.

Thanks a lot for the support!!

Hello,

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);

`

Thanks!

I meant:

`

fixture = new AggregateTestFixture<>(FlightObject.class);
flightCommandHandler.setRepository(fixture.getRepository());
flightCommandHandler.setEventBus(fixture.getEventBus());
fixture.registerInjectableResource(appliAView);

fixture.registerAnnotatedCommandHandler(flightCommandHandler);

`

The resource injected before the command handler obviously.

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.

Cheers,

Allard