Replay events and race conditions

lets say that i want to recreate my projection db tables. for simplicity there are 2 tables. first table holds companies and secend one, members of the companies
company record are created when CompanyCreatedEvent is emmited
and CompanyMemberCreatedEvent for new company member
below is kotlin syntax

@EventHandler
fun onMemberCreated(event: CompanyMemberCreatedEvent){
 val companyRecord=queryGateway.query(GetCompanyByIdQuery(event.companyId))
...
val newCompanyMember=CompanyMember(..., companyRecord.name, ...)
insert newCompanyMember to db
}

since CompanyCreatedEvent is first, do i have guarantee that when querying for company record this record will be there?
what is the best approach to deal with such cases?

Hi Radoslaw,

If both events belong to the same aggregate root i think you could handle both events (CompanyCreatedEvent, CompanyMemberCreatedEvent) with the same event processor and configure an org.axonframework.eventhandling.async.SequentialPerAggregatePolicy for this event processor (which is the default sequencing policy for tracking event processors as far as i know). This will make sure that the processor handles all events that belong to the same aggregate instance (i.e. having the same aggregate identifier) in the exact order as they were applied in the aggregate.

If the events belong to different Aggregates, things get a bit more complicated. When building our first axon application we built our projections in a simlar way (independent aggregates resulting in entities that depend on each other in the query projections). We ended up running all of our event processing for the query projections in a single event processor with a org.axonframework.eventhandling.async.SequentialPolicy which means full sequential processing of all events as they appear in the eventstore (across different aggregate identifiers). However, this meant a real huge performance penalty for our query model processing and we started removing such dependencies and instead only store the ids of related entities for the query model and join required information from related entities on the fly when querying the projection. In your case that would mean that you could for example simply store the companyId with your new CompanyMember in the projection and when someone is querying the CompanyMember you could simply join the Company and provide the name information on the fly.

Best Regards,
Jakob