You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up to JasperFx/jasperfx#569 / PR JasperFx/jasperfx#571. Sibling of JasperFx/marten#5052 — jasperfx#569 was written believing Marten was the only consumer of this API, but Polecat maintains its own pc_natural_key_X lookup table off the same NaturalKeyDefinition.
Required change (one line)
NaturalKeyEventMapping.Extractor changes from Func<object /* event data */, object?> to Func<IEvent, object?>. Widening it to the whole event is what makes an IEvent<T>[NaturalKeySource] handler bindable at all, and what lets a key be derived from event metadata.
Polecat has a single call site, and it already holds the real IEvent:
QueueOperationForEvent is shared by both the inline append path (ApplyAsync) and the rebuild path (QueueUpsertsForEvents), so that covers both.
What Polecat inherits for free
The discovery bugs are all upstream, so Polecat has the same exposure today and gets the same fixes on the version bump:
IEvent<T> handlers were silently dropped. A [NaturalKeySource] method taking IEvent<T> produced no mapping, no error and no log, so pc_natural_key_X was simply never written for that event type — a stale lookup after a key change, live and on rebuild alike. Worth a regression test on the Polecat side mirroring marten#5042's bug_5041_natural_key_should_be_updated_during_rebuild_when_handler_is_ievent, since Polecat's rebuild path (DocumentStore.EventStore.csNatural-key lookup table not repopulated on projection rebuild (parity with marten#4788) #259 re-emit) is its own code.
Handlers were invoked against a fabricated blank aggregate.Expression.New(docType) bypasses required-member enforcement, so a handler body touching any state other than the key threw out of the extractor and aborted the caller's SaveChangesAsync. That path is now last-resort and gated on the aggregate being safely constructible.
Unbindable [NaturalKeySource] methods now throwInvalidProjectionException from AssembleAndAssertValidity() instead of registering nothing. Worth a pass over the Polecat test suite for any projection quietly relying on a natural key mapping that never existed.
Also worth fixing while here
src/Polecat/Events/EventOperations.cs:748 tells users to "Configure a natural key via NaturalKey() in a SingleStreamProjection registration" — there is no such API, in Polecat or in JasperFx.Events. Until jasperfx#571 the only candidate (NaturalKeyBuilder<TDoc>.SetBy) had an internal constructor and was unreachable dead code, so that message pointed users at nothing.
So the message should name NaturalKeyFor(), and docs/events/natural-keys.md should document it as the explicit alternative to [NaturalKeySource] — plus the constraint the attribute path now enforces: the key has to be a function of the event alone, since the lookup table is maintained inline at append time where no prior aggregate exists under an Async snapshot lifecycle.
Blocked on a JasperFx.Events release carrying jasperfx#571.
Follow-up to JasperFx/jasperfx#569 / PR JasperFx/jasperfx#571. Sibling of JasperFx/marten#5052 — jasperfx#569 was written believing Marten was the only consumer of this API, but Polecat maintains its own
pc_natural_key_Xlookup table off the sameNaturalKeyDefinition.Required change (one line)
NaturalKeyEventMapping.Extractorchanges fromFunc<object /* event data */, object?>toFunc<IEvent, object?>. Widening it to the whole event is what makes anIEvent<T>[NaturalKeySource]handler bindable at all, and what lets a key be derived from event metadata.Polecat has a single call site, and it already holds the real
IEvent:src/Polecat/Events/Projections/NaturalKeyProjection.cs:96—mapping.Extractor(e.Data)→mapping.Extractor(e)QueueOperationForEventis shared by both the inline append path (ApplyAsync) and the rebuild path (QueueUpsertsForEvents), so that covers both.What Polecat inherits for free
The discovery bugs are all upstream, so Polecat has the same exposure today and gets the same fixes on the version bump:
IEvent<T>handlers were silently dropped. A[NaturalKeySource]method takingIEvent<T>produced no mapping, no error and no log, sopc_natural_key_Xwas simply never written for that event type — a stale lookup after a key change, live and on rebuild alike. Worth a regression test on the Polecat side mirroring marten#5042'sbug_5041_natural_key_should_be_updated_during_rebuild_when_handler_is_ievent, since Polecat's rebuild path (DocumentStore.EventStore.csNatural-key lookup table not repopulated on projection rebuild (parity with marten#4788) #259 re-emit) is its own code.Expression.New(docType)bypassesrequired-member enforcement, so a handler body touching any state other than the key threw out of the extractor and aborted the caller'sSaveChangesAsync. That path is now last-resort and gated on the aggregate being safely constructible.[NaturalKeySource]methods now throwInvalidProjectionExceptionfromAssembleAndAssertValidity()instead of registering nothing. Worth a pass over the Polecat test suite for any projection quietly relying on a natural key mapping that never existed.Also worth fixing while here
src/Polecat/Events/EventOperations.cs:748tells users to "Configure a natural key via NaturalKey() in a SingleStreamProjection registration" — there is no such API, in Polecat or in JasperFx.Events. Until jasperfx#571 the only candidate (NaturalKeyBuilder<TDoc>.SetBy) had aninternalconstructor and was unreachable dead code, so that message pointed users at nothing.jasperfx#571 makes it real as
NaturalKeyFor():So the message should name
NaturalKeyFor(), anddocs/events/natural-keys.mdshould document it as the explicit alternative to[NaturalKeySource]— plus the constraint the attribute path now enforces: the key has to be a function of the event alone, since the lookup table is maintained inline at append time where no prior aggregate exists under anAsyncsnapshot lifecycle.Blocked on a JasperFx.Events release carrying jasperfx#571.