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
{{ message }}
Repository navigation
Commit cf29990
Browse filesBrowse the repository at this point in the historyBrowse files
review: close the six surfaces a map newly REACHES now that codegen no longer throws
Every finding is a consequence of the same thing: while `SpringTypeMapper` threw on a
`field.map`, no downstream surface could ever see one. Removing the throw made six
paths reachable that had never been exercised, and each had been written as
"ObjectField or nothing".
1. PAYLOAD (medium-high). `SpringPayloadGenerator.resolveFieldType` routed a map past
the nested-payload arm into the plain type mapper, typing the component as the
SOURCE value object's FQN — a type the payload path never emits. `nestedTargetOf`
matched only `ObjectField`, so the target never entered the emission closure
either. A `@payloadRef` VO carrying a map-of-VO therefore emitted a
`<Name>Payload` naming a record nothing generated. Now routed through
`resolveMapFieldType`, which emits the nested payload and returns
`Map<String, <Target>Payload>`; `nestedTargetOf` agrees, as its javadoc requires.
2. C# PROJECTION (medium). The jsonb map config lived only in `EmitFieldTypeConfig`,
which never runs for a read-only `object.projection` — but `EntityGenerator` emits
the `Dictionary<string, V>` property for one anyway. A view exposing a map got a
property with no mapping, which is the exact failure the mapping exists to prevent.
The config is now a shared `MapJsonbConfig` called from both sites.
3. SORT ALLOWLIST (medium). Every map name landed in `SORT_ALLOWLIST`, so
`?sort=labels:asc` passed and lowered to `ORDER BY` over a jsonb column —
meaningless ordering on Postgres, 400 elsewhere, api-contract divergence. The
filter side was already safe, but only because no operator band matches a map.
4. UNRESOLVED REF (low). `mapValueJavaType` promised null for an unresolvable
`@objectRef` while `MetaDataUtil.getObjectRef` throws — and its own sibling
`mapValueObjectRefOf` catches. One dangling ref gave a not-found from the mapper
and a silent skip from the validation path. Now caught, as documented.
5. VALUE-OBJECT `@Valid` (low). The entity DTO's cascade was widened to span maps but
the VO generator's was not, so nested constraints went unenforced exactly one level
down.
6. PATCH (low). POST cascades into a map's value objects via `@Valid`; PATCH validates
per-field with `validateValue`, which does not cascade. PATCH could persist a
nested value object POST rejects. It now validates each map value.
Each fix carries a test that fails without it, including two the old assertions could
not have caught: the sort test also asserts a plain string STAYS sortable (so it
cannot pass on an empty allowlist), and the projection test asserts the property is
emitted before asserting the mapping is. The projection arm is compile-proven by
adding a map to `DbContextCompileTests`' projection, since it is a different emitter
from the entity one.
Java 246 green on `clean test`; C# 442 codegen + 1024 conformance + 291 render + 77
cli green.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013sjn9TaHoZFdDPF2dLcppv
0 commit comments