Updating state of Aggregate that exists

Is there a way to update an aggregate without checking if it exists already? I don’t want to Query anything if possible. I was thinking I could attempt to issue an UpdateCommand with the target identifier and if it fails, then firing off a CreateCommand. Any thoughts?

Hi Ryan,

You can use the @CreationPolicy(AggregateCreationPolicy.CREATE_IF_MISSING)
annotation on the command handler method which will either create an aggregate or act on an existing instance.
Check out our Reference guide for more details on the aggregate creation policies: https://docs.axoniq.io/reference-guide/axon-framework/axon-framework-commands/command-handlers#aggregate-command-handler-creation-policy

1 Like

Thanks, but we’re still on 4.0.4. We’ll try and upgrade, but are there any solutions for this version?

Edit: Upgrading to 4.3 seems to work fine, but any input on my question is appreciated.

Hi Ryan,

we’re currently doing the same as you suggested - we issue the create command and catch a possible CommandExecutionException that might occur before we issue the actual update command. Note that this was implemented before the @CreationPolicy and the improved exception handling was introduced, so it looks a bit clumsy and we’ll definitely refactor it to use @CreationPolicy for this use-case (which makes the clumsy exception handling obsolete):

    try {
        // try to create the aggregate if not exists
        CreateCommand createCmd = new CreateCommand(id, name);
        commandGateway.sendAndWait(createCmd);
    } catch (CommandExecutionException e) {
       // check if application aggregate already existed
       // currently relying on the Axon Exceptions
        if (e.getMessage().contains("[AXONIQ-2000]") || 
            e.getMessage().contains("The Unit of Work already has an Aggregate with the same identifier")) {
            // gracefully ignore if the app already existed
            log.debug("aggregate {}:{} already existed, skip creating.", id, name);
        } else {
            // rethrow and handle properly
            throw e;
        }
    }
    // update the aggregate
    UpdateCommand updateCmd = new UpdateCommand(id, newName);
    commandGateway.sendAndWait(updateCmd);

Best Regards,
Jakob

2 Likes

Thanks for the feedback Jacob!