Saga association properties

Docs:

https://docs.axoniq.io/reference-guide/implementing-domain-logic/complex-business-transactions/implementing-saga

https://docs.axoniq.io/reference-guide/implementing-domain-logic/complex-business-transactions/managing-associations

How does the “@SagaEventHandler(associationProperty=“sellOrderId”, keyName=“orderId”)” works?
I do not understand the doc.

The example below will not work since we erase the association key.
How to solve this issue?

One way is to change EventC and EventD for field “token” to have unique field name but that is not always possible.

Also I would rather use different token for each command so the corresponding event published have different token as well.

Example:

Have event:

EventA with field “myCustomId” (field is an object with custom toString()) => is published by Aggregate0
EventB with field “myCustomId” (field is an object with custom toString()) => is published by Aggregate0

EventC with string field “token” => is published by Aggregate1
EventD with string field “token” => is published by Aggregate2

`

@StartSaga
@SagaEventHandler(associationProperty = “myCustomId”)
public void handle(EventA event) {

var token1 = “random uuid value 1”
var token2 = “random uuid value 2”

// below associateWith does not work but events use both a field “token”

SagaLifecycle.associateWith(“token”, token1);
SagaLifecycle.associateWith(“token”, token2);

// send cmd1 to Aggregate1 with token1
commandGateway.send(cmd1);

// send cmd2 to Aggregate2 with token2
commandGateway.send(cmd2);

}

@SagaEventHandler(associationProperty = “token”)
public void handle(EventC event) {
// some logic
}

@SagaEventHandler(associationProperty = “token”)
public void handle(EventD event) {
// some logic
}

@EndSaga
@SagaEventHandler(associationProperty = “myCustomId”)
public void handle(EventB event) {
}

`

After reading the code source of:
AssociationValueEntry, SagaStore, SagaEntry, JpaSagaStore, etc.

It looks like it is in fact possible to do
`

SagaLifecycle.associateWith(“token”, token1);
SagaLifecycle.associateWith(“token”, token2);
`

Am I correct?

Hi,

You cannot use same associationProperty in multiple @sagaEvenHandler if saga event handler is using same event instance, ie if token1 and token2 are two different instance of same pojo.

It’s should be like
@sagaEventHandler(associationProperty (“unique”).

Thanks
Siddu

Sorry, I don’t really understand your answer.

After reading the source code, it seems that it is possible to define the same key multiple time for same Saga instance when value is different since the equals/hashcode checks both values

Yes, it is definitely possible for a Saga to be associated for two values with the same key.

Imagine a ShippingSaga. When an order can’t be shipped in a single shipment, you may and up with the saga being associated with both shipment. Thus, the key ‘shipmentId’ will appear twice. That simply means that this Saga instance’s methods will be invoked when either of the two shipments is mentioned in an event.

However, you cannot have two SagaEventHandler methods for the same event.

Hope this helps.
Cheers,

Allard

ok thanks.

For:

you cannot have two SagaEventHandler methods for the same event.

In my example I do not use same event twice in same Saga, so no problem.

There is no issue to use same event in:

  • different Saga instance of same type (should be very rare case to happen, I have no case yet of that) → same event processor but different saga instance

  • different Saga type → different event processor

Small correction on my statement: you can have two handlers for the same event, but only 1 of the handlers will ever be invoked on each Saga instance. Axon will try to pick the most ‘specific’ instance.

It is perfectly fine for two Sagas to handle the same event.