Can 2 Aggregates be tied without using saga - (throws unique constraint error)

I have created 2 separate Aggregates -Say Aggregate A and Aggregate B and both using same identifier.
I have 2 separate command handlers to call them . What i see if If i invoke aggregate B and I pass the same identifier as A it starts with ‘0’ sequence and throws the constraint.
I was assuming axon was smart enough to understand the next sequence for Aggregate B continuing from Aggregate A.
Has any one faced a similar issue ?

Thanks
Sandeep

First thing that popped in my head, are those really two different aggregates? If they are not then look if you can model into them as entities.
Follow the below, if it applies in your case
https://docs.axoniq.io/reference-guide/implementing-domain-logic/command-handling/multi-entity-aggregates

If they really are two aggregates, maybe you can start a saga and create another aggregate from saga. So, your saga will send a command to other aggregate in another bounded context and send aggregate A’s UUID.
Also, sequencing is only guaranteed within an aggregate. Please read the below post why UUID’s make a better choice with UUID’s.

https://stackoverflow.com/questions/56400531/what-is-the-best-way-to-generate-axon-sequence-number-while-working-with-multipl

Hi Sandeep,

I had this behavior in Axon 3, knowing that you can cannot share the same aggregate id between two aggregates of different types if theirs events are stored in the same event store (the domain_event_entry if you use a relational database). The reason behind this is a database constraint that doesn’t take the aggregate type into account when checking the consistency of the sequence number.

To be honest, I was hoping this problem would disappear in Axon 4 but I didn’t test yet with Axon server.

Hi all,

Axon still maintains the unique key constraint on the aggregate identifier - sequence number combination.

There are several occurrences of this question present on the user group, which mainly come down to using typed identifiers.
The toString() method of your typed identifier would then not only return the (I would suggest) UUID, but pair it with the Aggregate Type.

Earlier version of the framework did allow two distinct Aggregate implementations to reuse a given identifier.
However, this meant that if you retrieve a stream of events for an Aggregate, which by definition is based on the aggregate identifier, the framework was inclined to inspect the Aggregate Type before hand too.
The API was (greatly) simplified by not having to search this type beforehand, with “the drawback” of require users to provide unique identifiers.

At the time this was deemed a fair trade off, especially given the resolution I’ve provided above.
We still feel this way, although you of course never know if things change in the future.

Hope this sheds some light on this design decision.

Cheers,
Steven

Thanks Steve - so looks like Saga is the only way to tie 2 different Aggregates ?

Hi Sandeep,

More simply put, an Event Handler can do the job.
A Saga is just a more direct way to describe a single connection between two (or more) Aggregate and/or Bounded Contexts.

Depending on the issue you are trying to resolve, you can go either ways.

If it’s complex in the sense that it requires to keep state of the said transaction, has a notion of time in it and associations to several Aggregates?

Then a Saga would be the best fit.

If you do not have to keep specific state of the given transaction, then I’d already be more doubtful whether a Saga is what you need.
In the end, it all depends on the exact domain and use case of the issue.

Hope this clarifies things for you Sandeep!

Cheers,
Steven

Hey Steve - unfortunately requirement is to have a relationship between multiple bounded contexts.

Here’s the use case - I’m trying to build a ticketing center - The user opens a ticket (Ticketing Aggregate with ticket _id as unique id) and it can trigger event to child components to act on that ticket. That child components can be a (DevTeamAggregate)Dev Team domain or (QATeamAggregate)QA team Domain or (OperateTeamAggregate)Operate Team domain…

You might have guessed by now that on UI we need to see all the events tied to this ticket#. so there has to be a common key that has to bind all the teams.

can this be achieved without Saga ?

Regards
Sandeep Chandan

Hi Sandeep,

If the UI has “the request for data”, then you are talking about queries which you should target towards the Query Model.

This is a distinctly separate concern from your Aggregates, which are the Command Model within your application.

Nothing within the framework withholds you from ingesting events from multiple different Aggregate instances to group them into a Query Model directly solving this exact issue.

If you however require dedicated associations between your Aggregates, you will have to imply some process to achieve these links.
This could be done through a Saga, but I don’t think that’s necessary “just” to create links.
A regular Event Handling Class which is aware how to actively tell Aggregate X that it’s associated to Aggregate Y makes sense.

On an even higher level you can try to figure out whether these Aggregates are in essence Entities which reside under a larger Aggregate Root.
Whether this is the case highly depends on your domain and application of course.

Hope this sheds some light on your situation.
If not, a more direct connection can be laid with AxonIQ to support you with design issue you might have.
We provide a Proof of Concept service for example, where any such issue can be discussed in far more detail than through this forum.

Cheers,
Steven

Thanks Steve - Your post really helps.
I realized , it could be done without Saga by correctly modelling the aggregates .