@GeneratedValue for aggregate id

As from documentation, one doesn’t have to include aggregate id in the first creation command, but in reality it fails with an exception:

AxonServerCommandDispatchException: The command [PlaceOrderCommand] does not contain a routing key

I already considered this topic.

All my code is written in Kotlin.


With Kotlin’s “no-args” and “jpa” plugins, I was able to create no args constructors for @Entity and @Aggregate implicitly. Also, for now, I feel it’s best to call the database sequence manually.


@Table(name = "orders")
data class OrderWriteModel(@Id val id: Long)

Hello, it seems like you are mixing two ideas here.

There are two types of aggregates, state stored and event sourced, it is not good practice to use the repository within an aggregate especially within event sourced aggregate inside it’s EventSourcing handler.

First, you are going to ‘save’ the OrderWriteModel each time you handle (any) command on that aggregate, preety waste of resources.
Second, what if your event sourcing fails due to the save of the write model?

When you really really need to depend on some external repository, then imho you should model your aggregate around some service that could provide every data you need in your domain model, and then you could use that domain service inside aggregate.

(Keep in mind im not sure about my claims since im new to these things so i might be completely wrong)

Hi Sam,

Robert is right on this one. Remember that the aggregate you are creating is your wite model. So having another (state stored) write model inside an event sourced aggregate is most likely something that overcomplicates your design.

Also, updating this information from an EventSourcingHandler will have this repo.save() method invoked every time the Aggregate is loaded.

Try modeling all behavior into your aggregate. If you store information for retrieval elsewhere, you probably need a read model for that.


Thank you!

I see saving after replaying events is very inefficient and also Axon has GenericJpaRepository already under the hood.

Here is what I did:

Hi Sam,

Regarding your initial question on the does not contain a routing key exception you encountered, you must have noticed this trace originated from the AnnotationRoutingStrategy.

This is configured for you by default, and by default, will expect an @RoutingKey annotated field in the command message.
Note that the @TargetAggregateIdentifier annotation is meta-annotated with @RoutingKey.

You can configure the AnnotationRoutingStrategy to take different approach to the none-existence of a routing key in your command message.

This can be done by creating a AnnotationRoutingStrategy with another UnresolvedRoutingKeyPolicy.

The default UnresolvedRoutingKeyPolicy is ERROR, exactly why you’re seeing this message.

Consider using something like static or random in this scenario.

Additionally, I think it’s justified to clarify this in the documentation.
The notion is still correct, granted you’re not utilizing a distributed solution for the command bus (as in that scenario, there is no need for a Routing Strategy), but this should be made clear there.
Do you mind be more specific where the documentation states an Aggregate Identifier isn’t required for the Aggregate-Creation-Command, so that we may adjust this bit?

Looking forward to your response, and I of course hope this helps you out Sam!


Thank you, Steven, for your response!

This is useful information!
The part is here https://docs.axoniq.io/reference-guide/implementing-domain-logic/command-handling/aggregate “Commands that create an Aggregate instance do not need to identify the target aggregate identifier, as there is no Aggregate in existence yet. It is nonetheless recommended for consistency to annotate the Aggregate Identifier on them as well.”

It is also mentioned in the “Note” on the same page:
When the @CommandHandler annotation is placed on an aggregate’s constructor, the respective command will create a new instance of that aggregate and add it to the repository. Those commands do not require to target a specific aggregate instance. Therefore, those commands do not require any @TargetAggregateIdentifier or @TargetAggregateVersion annotations, nor will a custom CommandTargetResolver be invoked for these commands.

Hi Sam,

Thanks for specifying the section which was unclear on this.
I’ve just pushed a change to the reference guides for Axon 4.0 and 4.1 be a little more specific on the Aggregate Creation Command’s necessity for a routing key, or the configuration of a different Routing Strategy.