EventSource handler being invoked when not expected in the Aggregate with multiple EventSource handler implementation.

Hey guys,

I am new to the axon framework, have been using it from few weeks time.
I have got the project which contains the spring controller having the API controller code snippet as

Hi All,

I did spend some time preparing the simple demo app and it is here
https://github.com/dallaybatta/axon-demo

The application can be started and the behaviour can be seen as explained in my first post, here is what needs to be done to get the issue

  1. Start the application
  2. Go to the swagger-ui at http://localhost:9082/swagger-ui.html
  3. Create the agency using http://localhost:9082/swagger-ui.html#/axon-test-api/createAgencyUsingPOST
  4. Check from the embedded h2 via console at http://localhost:9082/h2console, make sure you have JDBC URL as “jdbc:h2:file:./target/axon-sample” in the ui screen.
  5. You should be able to see the Agency created via step [3]
    6 Next do the update to the Agency via http://localhost:9082/swagger-ui.html#/axon-test-api/updateAgencyUsingPUT, the same thing happens when the Delete is called.

You will see the Agency creation being done too, the CreateAgentEvent is triggered too although only the UpdateAgentEvent should have been triggered for update invocation.
The interesting point to note here that there is not invocation of the CreateAgentCommand handler which makes me think that axon is doing something which is triggering the CreateAgentEvent when the update and delete commands are triggered.

Also I observer if I don’t use the generated keys in the Agent Entity things work as expected the axon is not making the additional calls.

Can someone from the core team have a look at this one?

Regards,
Vicky

I have enabled the logging for the axonframework and see this

Sorry I could not post more details in my last post as it was posted accidentally, it is clear from the above post that the axon is making the call to @EventSourcingHandler( corresponding to create event) which I don’t expect.

Can someone from the core team give some pointers how to avoid the event processing from the create when update is invoked, this happens when the JPA entity involved is having a ID with autogenration annotation?

Hi Vicky,

Note that Event Sourcing is done every time an Aggregate is retrieved from the repository, as this is the essence of Event Sourcing.
The events are the source of your Aggregate, so retrieving it from a repository means you’re retrieving the events which constitute an Aggregate and let the Aggregate’s Event Sourcing Handlers handle them again to reinstantiate the Aggregate.

Thus, any outbound calls from Event Sourcing Handlers are a bad idea in general, as they will be called every time the Aggregate is retrieved.

From your sample I see that the Aggregate relies heavily on all kinds of services anyhow, as you’re wiring everything in.
Note that doing so will block all other commands from being handled by the Aggregate, as an Aggregate instance is being locked when handling a command.

Performing operations as a response to a given event should instead by dealt with in a separate Event Handling Component, on the Query side of your application.
Services you might need in your Command Handlers should strictly be used to decided whether the given command should be handled or not.

This follows from that fact that a command is “a request to perform some action”.
As it’s a request, validating the request is what you should do in the command handler, not actually performing the request.

Hope this sheds some light on the situation Vicky.

Cheers,
Steven

This hack got it working, however I think it is not the right approach

Hi Vicky,

I assume my response appeared right after you’ve send your follow up question.
Do know that this is a user group to which everybody can answer.
If you want fast support from the development team, a better approach would be to contact us for development support.

Cheers,
Steven

Hi Steven,

Thanks for you response and followup. I understand that it a public forums and developers do there best to reply here, I have been in this role too ;).

Thus, any outbound calls from Event Sourcing Handlers are a bad idea in general, as they will be called every time the Aggregate is retrieved.
Yep, I think I missed to implement it incorrectly as it was explained here
https://github.com/abuijze/bootiful-axon/blob/master/demo-complaints/src/main/java/com/example/DemoComplaintsApplication.java

Regards,
Vicky

Hi Vicky,

Happy to hear that you’ve found the issue at hand!
If you hit up any new problems you cant find a solution to, do not hesitate to post a new thread on this user group! :slight_smile:

Cheers,
Steven

Hi Steven,

I have made the changes and am getting the error yet

Hi Vicky,

I am not entirely sure what aggregate id you’re using, but I am assuming you’re reusing the same aggregate id for all three of your aggregates.
If this is true, than that’s the issue you’re encountering.
Axon places a constraint on the aggregate-id / sequence number combination in the event store.

As you’ve decided to model this as three aggregates, publishing an event from all three, with the exact same aggregate identifier, will end you up with the exception you’re seeing.
Axon uses the toString() function on the @AggregateIdentifier annotated field in your Aggregate class to deduced what to fill the aggregateId column with.
Thus, a way to work around this whilst still being able to use the same UUID would be to provide an actual object for your Aggregate Id, which would append the Aggregate Type in the toString() function.

However, we typically suggest to use a random UUID as the Aggregate Identifier.

This should ensure you will not encounter duplicate identifiers.

A part from what I’ve just shared though, I’d like to give you another pointer based on the GitHub repository you’ve shared.
I am by no means a subject matter expert of your domain, but I have not ever encountered the need to have a specific Aggregate for a create, delete and update task.

Task aggregates are definitely imaginable, but going as generic to create CRUD Aggregates for tasks does not seem to be the right approach, to be honest.
Then again, as I just pointed out, I am not the subject matter expert of your domain.

Hope this helps you out Vicky.

Cheers,
Steven

Hi Steven,

I got it working finally with the changes here :wink:
https://github.com/dallaybatta/axon-demo/blob/master/src/main/java/org/dallaybatta/axondemo/task/AgentTask.java

Thanks for your kind help and support.

Thanks,
Vicky