Best practice for 'duplicate' or replayed create commands

Hi there,

I’m looking for some advice around the best way to handle a ‘create’ command for an aggregate with the same Id that is sent multiple times.

I have 2 use cases where this appears:

  1. replaying external events (service B) triggers a saga which sends a create command to service A:
  • After restarting service B the saga and it’s commands are replayed
  • Effectively sending the create command to service A again
  1. multiple external aggregates (service B) relate to the same aggregate (service A)
  • and I want to ensure the aggregate exists (and if not is created) in service A, when an aggregate is also created in Service B

So far I’ve explored:

  • Conditionally applying an event on handling the create command
  • but it seems the command does not ‘complete’ without calling apply- Generating multiple created events
  • but this doesn’t feel correct, and is in fact misleading
  • It was only really created once- We’d end up 1:1 create events for Service B and A.- Generating a distinct event when not created IE. AggregateNotCreated
  • Again, this doesn’t feel quite right as the event has no side-effects and probably never will
  • If I had to hedge my bets, I’d say this argument isn’t strong enough and this is Event Sourcing.
  • It’s still going to produce 1:1 events between service B and A- Keeping a local projection of Service A’s aggregates within B, conditionally sending the commands
  • I’m concerned about the projection being stale, and that the commands may still fail- And other’s I’ve probably forgotten…
    Any advice is much appreciated.

Thanks,
Craig

Hi Craig,

have you seen the new @CreationPolicy annotation you can put on command handler methods? The CREATE_IF_MISSING option sounds a lot like what you're describing.

The documentation is here: https://docs.axoniq.io/reference-guide/implementing-domain-logic/command-handling/aggregate#aggregate-command-handler-creation-policy

Regards,
  Levi

I’m using that (it’s great). But it still requires me to call apply() for the command to complete and thus generate a second create event.

Ah, that sounds limiting… normally, an aggregate decides whether it applies 0, 1 or more events, so I don’t see why this case would be different.

I’m fairly certain that in our project we have an aggregate with a ‘create if missing’ policy that has a conditional apply, so if your design does not impose a second event (and rereading your original post tells me it doesn’t), that option should work (and is the cleanest one as well, I think).

Hi Craig,

you shouldn’t need to apply events for a transaction to be completed normally. You do in case of a CREATE (otherwise the create didn’t happen), but when updating, it’s perfectly fine to not apply any events.
What made you believe otherwise?

Cheers,

The fact I had a conditional apply() in my create command handler, IE.
//if not already created
///then apply create event
//otherwise do nothing

And I found that calling commandGateway.sendAndWait(…) did not return/unblock unless I had an apply on the command handler side.
(I may not remember correctly as I’ve been bouncing a round a lot now. If I get another chance I’ll investigate again.

I had more “success” with using a callback commandGateway.send(…,…).

The behaviour I’m after really is create if needed and let me know when you’re done.
In the case of generating an event, it’s easy to know when done, otherwise I need to add an asymmetrical mechanism just for the negative case. In the end I generated an event for the negative case too. I still appreciate that’s not quite ‘right’ but at-least it kept my command producer more symmetrical.

Thanks,
Craig