Skip to content

Read renamed fields from their former names - #237

Merged
DavidBadura merged 1 commit into
3.0.xfrom
field-aliases
Oct 19, 2026
Merged

DavidBadura merged 1 commit into
3.0.xfrom
field-aliases

Conversation

@DavidBadura

Copy link
Copy Markdown
Member

Renaming a field breaks the stored data, so far that needed an upcaster which moves the value from the old to the new key. NormalizedName accepts aliases now, similar to the event aliases in event-sourcing:

#[NormalizedName('email', aliases: ['mail'])]
public Email $email;

While hydrating, the first alias in the data is used if the field itself is missing. Extracting always writes the field name, so the stored data catches up over time. Field names and aliases have to be unique within a class and its parents, the metadata factory throws DuplicatedFieldNameInMetadata otherwise.

The ReflectionMapper only looks at the aliases if the field is missing. The generated mappers copy the alias into the field right before the assignment, classes without aliases get exactly the same code as before. The aliases are part of the fingerprint, and so is the property name now: renaming only the property behind an unchanged field name used to keep the outdated generated mapper.

Middlewares see the data as it is stored. The CryptographyMiddleware runs before the mapper, so it now also finds sensitive data and subject ids stored under an alias, otherwise a renamed sensitive field would not be decrypted.

#233 intersects the data with the fields kept by a property filter, which would drop the aliases. Whichever of both is merged second gets the fix for that.

NormalizedName accepts aliases now. While hydrating, the first alias in the
data is used if the field itself is missing, extracting always writes the field
name. This covers the most common upcasting case, a renamed field, without
writing an upcaster.

The generated mappers copy the alias into the field before the assignment,
classes without aliases get the same code as before. The cryptography
middleware also finds sensitive data and subject ids stored under an alias.
@github-actions

Copy link
Copy Markdown

Hello 👋

Here are the most recent benchmark results, compared against 3.0.x. Time is the mode over the iterations in the its column, with the relative standard deviation in brackets.

GeneratedHydrator

subject revs its memory base current diff
benchHydrate1Object 1000 5 1.855mb -21.23% 0.789μs (±0.43%) 0.802μs (±2.80%) +1.64%
benchExtract1Object 1000 5 1.855mb -21.23% 0.931μs (±0.67%) 0.939μs (±1.72%) +0.81%
benchHydrate1000Objects 3 5 1.855mb -21.23% 765.890μs (±1.39%) 768.630μs (±0.90%) +0.36%
benchExtract1000Objects 3 5 1.855mb 0.00% 488.763μs (±0.91%) 491.454μs (±0.77%) +0.55%

StackHydrator

subject revs its memory base current diff
benchHydrate1Object 1000 5 1.855mb 0.00% 1.525μs (±0.73%) 1.544μs (±3.63%) +1.26%
benchExtract1Object 1000 5 1.855mb 0.00% 1.925μs (±1.69%) 1.921μs (±5.83%) -0.19%
benchHydrate1000Objects 3 5 1.855mb 0.00% 1.493ms (±0.95%) 1.505ms (±1.19%) +0.81%
benchExtract1000Objects 3 5 1.855mb 0.00% 1.453ms (±0.62%) 1.443ms (±1.54%) -0.67%

StackHydratorWithLazy

subject revs its memory base current diff
benchHydrate1Object 1000 5 1.855mb 0.00% 0.359μs (±2.60%) 0.343μs (±2.41%) -4.49%
benchHydrate1ObjectTriggerInit 1000 5 1.855mb 0.00% 2.105μs (±4.07%) 2.118μs (±0.54%) +0.61%
benchHydrate1000Objects 3 5 1.855mb 0.00% 332.256μs (±1.07%) 331.703μs (±0.52%) -0.17%
benchHydrate1000ObjectsTriggerInit 3 5 1.855mb 0.00% 2.075ms (±0.97%) 2.105ms (±1.75%) +1.43%

StackHydratorWithCryptography

subject revs its memory base current diff
benchHydrate1Object 1000 5 1.855mb 0.00% 2.431μs (±1.23%) 2.649μs (±0.52%) +8.97%
benchExtract1Object 1000 5 1.855mb 0.00% 7.856μs (±2.78%) 7.854μs (±0.43%) -0.02%
benchHydrate1000Objects 3 5 1.855mb 0.00% 2.389ms (±0.99%) 2.564ms (±0.78%) +7.30%
benchExtract1000Objects 3 5 1.855mb 0.00% 7.227ms (±1.42%) 7.376ms (±0.68%) +2.06%

GeneratedHydratorWithCryptography

subject revs its memory base current diff
benchHydrate1Object 1000 5 1.855mb 0.00% 1.695μs (±0.55%) 1.846μs (±0.68%) +8.89%
benchExtract1Object 1000 5 1.855mb 0.00% 6.618μs (±4.11%) 6.543μs (±1.48%) -1.13%
benchHydrate1000Objects 3 5 1.855mb 0.00% 1.634ms (±0.34%) 1.824ms (±0.81%) +11.63%
benchExtract1000Objects 3 5 1.855mb 0.00% 6.024ms (±0.52%) 5.982ms (±0.40%) -0.69%

This comment gets updated every time a new commit comes in.

@DavidBadura DavidBadura added the enhancement New feature or request label Oct 19, 2026
@DavidBadura DavidBadura added this to the 3.0.0 milestone Oct 19, 2026
@DavidBadura
DavidBadura merged commit e1203a3 into 3.0.x Oct 19, 2026
16 of 17 checks passed
@DavidBadura
DavidBadura deleted the field-aliases branch October 19, 2026 05:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants