fix(#4625): reading events/snapshots stored without a revision [DRAFT - reproduction, solution under discussion]#4626
Draft
MateuszNaKodach wants to merge 1 commit into
Draft
Conversation
Pin the current behavior where MessageType's compact constructor rejects an empty or null version. This is the root cause of #4625 when reading Axon Framework 4 events/snapshots that were stored without a revision. No fix applied yet; the solution is under discussion.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Problem
Reading Axon Framework 4 events/snapshots that were stored without a revision crashes under AF5 with:
Reported in #4625 (and hit by at least one other user). AF4 never required a revision —
SimpleSerializedTypeallowed anullrevision and Axon Server stores an absent revision as an emptyString. AF5'sMessageTypecompact constructor instead rejects bothnulland""versions, so any read path that rebuilds aMessageTypefrom stored data (new MessageType(payloadType, payloadRevision)) blows up on legacy data.What this (DRAFT) PR contains
Only a reproduction — no fix yet. It adds unit tests pinning the root cause:
MessageType's compact constructor rejecting an empty version, anullversion, and the exactnew MessageType(name, "")call the storage engines make.MessageTypeTest.GivenStoredMessageWithoutVersion— ✅ passing (asserts the current, broken behavior).The companion runtime reproduction (store an event without a revision in Axon Server, then read it back) lives in the connector repo's matching
fix/4625_MessageWithoutRevisionbranch.Solution — under discussion⚠️
The obvious fix is to default an absent (
null/empty) version toMessageType.DEFAULT_VERSION("0.0.1") on read. But that may not be safe for everyone, and that's the open question:null/""→"0.0.1"is lossy. Applications that already, deliberately, treat "no revision" (legacy/AF4) differently from an explicit"0.0.1"would suddenly see legacy data masquerading as0.0.1. The two become indistinguishable. Today the only behavioral consumer ofversionis the snapshot compatibility gate (SnapshottingEntityLifecycleHandler), which degrades safely (mismatch → full replay) — but we shouldn't assume version stays purely informational forever, or that downstream apps see it that way.null/""→DEFAULT_VERSION. One-place fix; every read path inherits it; removes fail-fast on a genuinely missing version in new code.MessageType(e.g.ofNullableVersion/versionOrDefault) — keeps the constructor strict; each read site opts in.LegacyMessageTypes.messageType(type, revision)) — strongest "legacy only" signal; but the read paths are normal framework code, so theLegacy*label is debatable.0.0.1, so legacy data stays distinguishable from genuinely-0.0.1data (trade-off: legacy snapshots would never be trusted by the version gate).Feedback welcome on which direction to take before this leaves draft.
Relates to #4625.