Repository navigation
[WP14] Leaf-spec constructor validation & one-shot Iterable consumption #196
Copy link
Copy link
Open
Labels
status: ready-for-agentFully specified and ready for an autonomous AFK agent to implementFully specified and ready for an autonomous AFK agent to implementtype: bugSomething isn't workingSomething isn't working
Description
此內容由 AI 產生(specification-mapper 全庫審查 2026-07-16.執行圖)。
Work package WP14 · findings: COR-14, MAINT-06, MAINT-07, TEST-08 · worst severity: medium · effort: S
From the 2026-07-16 whole-codebase review of branch jakarta (snapshot 7de4a33; modules mapper/ + starter/). Every finding below is CONFIRMED by independent adversarial verification. File:line coordinates are from the snapshot and may have drifted.
Findings
COR-14 — Between and In consume the value Iterable multiple times, breaking one-shot Iterables (correctness, medium)
- File:
mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Between.java:57(andIn.java) - Evidence:
Between's constructor streams the Iterable to count elements, thentoPredicatestreams it again (and again on every execution);In.toPredicatere-streams per execution. A one-shot Iterable (stream-backed, cursor-backed) is exhausted after the first traversal — later traversals silently see nothing or throw.
MAINT-06 — Between never validates elements are Comparable (maintainability, low)
- File:
mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Between.java:67 - Evidence: elements are cast
(Comparable<?>)at query time — a bad element surfaces as a rawClassCastExceptionfar from the mapping site, unlike the fail-fastComparableSpecification/BooleanSpecificationsiblings.
MAINT-07 — LIKE family accepts any Object and silently coerces via toString (maintainability, low)
- File:
mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Like.java:52
TEST-08 — Between constructor-validation branches largely untested (testing, medium)
- File:
mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/BetweenTest.java:39 - Note: PR fix(mapper): unwrap reflective spec construction exceptions in toSpec #189 (post-review) added the element-count mapper-path case; the remaining branches — non-Iterable value, non-Comparable elements, one-shot Iterable — are still uncovered.
Plan
- In
BetweenandInconstructors, materialize the incomingIterableonce into an immutableListand havetoPredicateuse the materialized copy (fixes COR-14; single traversal ever). Between: validate at construction that there are exactly 2 elements (existing) and that both are non-nullComparable, throwing a descriptiveTypeMismatchException-style error (MAINT-06).- LIKE family: validate the value is a
CharSequenceat construction, throwingTypeMismatchExceptionotherwise, consistent with the type-checked siblings (MAINT-07). Release-note the tightening (previously any Object wastoString-coerced). - Tests (TEST-08): a stream-backed one-shot Iterable through
SpecMapper.toSpecexecuted twice; non-ComparableBetweenelements fail attoSpec; LIKE with a non-CharSequence fails attoSpec; remaining constructor branches ofBetween/Incovered.
Acceptance criteria
- A one-shot Iterable criteria maps and executes correctly across repeated query executions.
- Invalid values fail at
toSpecwith descriptive exceptions instead ofClassCastExceptionat query time. - New tests from step 4 pass; regression:
make testgreen.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
status: ready-for-agentFully specified and ready for an autonomous AFK agent to implementFully specified and ready for an autonomous AFK agent to implementtype: bugSomething isn't workingSomething isn't working
Activity