Commanded calling apply/2 on wrong aggregate
manoadamro opened this issue · comments
I stumbled accross this problem while trying to create a new aggregate (rather than having everything all in one)
but no matter what I do, it doesn't seem call execute on any aggregate, but tries to call apply on the wrong one (and fails to find it).
Have I misunderstood how the router works? (snippet below)
Plan:
PatientAggregate: CreatePatient -> PatientCreated
DiffAggregate : AddChunk -> ChunkAdded
Reality:
PatientAggregate : ??? -> ???
DiffAggregate : ??? -> PatientCreated
Router:
identify(DiffAggregate, by: :system_id)
dispatch(AddChunk, to: DiffAggregate)
identify(PatientAggregate, by: :system_id)
dispatch(CreatePatient, to: PatientAggregate)
PatientAggregate:
def execute(%__MODULE__{system_id: nil}, %CreatePatient{system_id: system_id, patient: patient})
returns PatientCreated
def apply(%__MODULE__{}, %PatientCreated{system_id: system_id, patient: patient})
DiffAggregate:
def execute(%__MODULE__{system_id: system_id}, %AddChunk{system_id: system_id, chunk: new_chunk})
returns ChunkAdded
def apply(%__MODULE__{system_id: nil}, %ChunkAdded{system_id: system_id, chunk: chunk, chunks: chunks} )
Dispatch
Application.dispatch(%CreatePatient{
system_id: patient_id,
patient: patient
})
The Error:
(codepilot 0.1.0) lib/codepilot_events/batch_file_uploads/aggregates/diff_aggregate.ex:33: CodepilotEvents.BatchFileUploadEvents.Aggregates.DiffAggregate.apply(
%CodepilotEvents.BatchFileUploadEvents.Aggregates.DiffAggregate{
chunks: ..., last_chunk: ..., system_id: ...
},
%CodepilotEvents.Patients.Events.PatientCreated{
patient: %{
age: ..., id: ..., practice_id: ..., system_id: ...
},
system_id: ...
}
)
As you can see, despite what the router is configured to do, it calls PatientCreated
on the DiffAggregate
instead of the PatientAggregate
The line (33) it mentions in the error is in fact:
def apply(%__MODULE__{system_id: _system_id}, %ChunkAdded{chunk: chunk, chunks: chunks})
which is the only apply function in this new aggregate, so it fails to match
It looks like you are sharing the same aggregate identity (:system_id
) between two different types of aggregates. This means that events persisted for one type of aggregate will be retrieved when loading the other aggregate type for the same system_id
.
You can use an identity prefix in the router to differentiate between the two aggregate types so that they can share a system_id
as follows:
identify(DiffAggregate, by: :system_id, prefix: "diff-")
dispatch(AddChunk, to: DiffAggregate)
identify(PatientAggregate, by: :system_id, prefix: "patient-")
dispatch(CreatePatient, to: PatientAggregate)