此內容由 AI 產生(specification-mapper 全庫審查 2026-07-16.執行圖)。
Work package WP13 · findings: COR-15, COR-16, TEST-09, MAINT-08, MAINT-09 · worst severity: medium · effort: M
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-15 — Field-level @Or on the first-declared field is silently ignored (correctness, medium)
- File:
mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Conjunction.java:38
- Evidence:
CompoundSpecification.toPredicate folds via a seedless specs.stream().reduce(this::combine); combine(result, element) inspects only the element's wrapper. The first-declared spec becomes the accumulator, so its Or wrapper is never examined: [@Or nickname, name] yields nickname AND name (the @Or silently dropped) while the reverse order yields name OR nickname.
- Failure scenario: the same annotation produces opposite SQL depending on field declaration position — silently wrong result sets.
COR-16 — Mirror defect: field-level @And on the first-declared field of an @Or class is silently ignored (correctness, medium)
- File:
mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Disjunction.java:38
- Evidence: same seedless-reduce mechanics as COR-15, mirrored for
And under Disjunction.
TEST-09 — No test pins first-position @Or/@And; combine() has no direct unit tests (testing, low)
- File:
mapper/src/test/java/tw/com/softleader/data/jpa/spec/SimpleSpecificationResolverTest.java:438
MAINT-08 — Order-dependent fold semantics over an unordered Collection type (maintainability, low)
- File:
mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/CompoundSpecification.java:39
- Evidence:
specs is a Collection, whose iteration order the API does not guarantee, yet the fold's outcome depends on it.
MAINT-09 — A field annotated with both @And and @Or silently resolves to And (maintainability, low)
- File:
mapper/src/main/java/tw/com/softleader/data/jpa/spec/SimpleSpecificationResolver.java:88
Plan
- Rework the
CompoundSpecification fold so every element's wrapper is honored, including the first. Behavioral target: permutation invariance — any declaration order of the same annotated fields yields the same SQL ([@Or a, b] ≡ [b, @Or a] → b OR a; mirror for @And under Disjunction).
- Narrow the
specs field/constructor type from Collection to List to make ordered folding an explicit contract (MAINT-08).
- In
SimpleSpecificationResolver, reject a field carrying both @And and @Or with a descriptive exception instead of silently picking And (MAINT-09).
- Tests (TEST-09): first-position
@Or under class-level AND; first-position @And under class-level OR; permutation-equivalence assertions; direct unit tests for Conjunction/Disjunction.combine.
- Release note: previously-ignored first-position wrappers now take effect — affected consumers' result sets change. Frame as a bug fix restoring the annotation's documented semantics.
Acceptance criteria
- The same annotated criteria class produces identical SQL for every field declaration order (COR-15/16 scenarios no longer reproduce).
@And + @Or on one field fails fast with a descriptive message.
- New tests from step 4 pass; regression:
make test green.
Work package WP13 · findings: COR-15, COR-16, TEST-09, MAINT-08, MAINT-09 · worst severity: medium · effort: M
From the 2026-07-16 whole-codebase review of branch
jakarta(snapshot 7de4a33; modulesmapper/+starter/). Every finding below is CONFIRMED by independent adversarial verification. File:line coordinates are from the snapshot and may have drifted.Findings
COR-15 — Field-level
@Oron the first-declared field is silently ignored (correctness, medium)mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Conjunction.java:38CompoundSpecification.toPredicatefolds via a seedlessspecs.stream().reduce(this::combine);combine(result, element)inspects only the element's wrapper. The first-declared spec becomes the accumulator, so itsOrwrapper is never examined:[@Or nickname, name]yieldsnickname AND name(the@Orsilently dropped) while the reverse order yieldsname OR nickname.COR-16 — Mirror defect: field-level
@Andon the first-declared field of an@Orclass is silently ignored (correctness, medium)mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Disjunction.java:38AndunderDisjunction.TEST-09 — No test pins first-position
@Or/@And; combine() has no direct unit tests (testing, low)mapper/src/test/java/tw/com/softleader/data/jpa/spec/SimpleSpecificationResolverTest.java:438MAINT-08 — Order-dependent fold semantics over an unordered
Collectiontype (maintainability, low)mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/CompoundSpecification.java:39specsis aCollection, whose iteration order the API does not guarantee, yet the fold's outcome depends on it.MAINT-09 — A field annotated with both
@Andand@Orsilently resolves to And (maintainability, low)mapper/src/main/java/tw/com/softleader/data/jpa/spec/SimpleSpecificationResolver.java:88Plan
CompoundSpecificationfold so every element's wrapper is honored, including the first. Behavioral target: permutation invariance — any declaration order of the same annotated fields yields the same SQL ([@Or a, b]≡[b, @Or a]→b OR a; mirror for@AndunderDisjunction).specsfield/constructor type fromCollectiontoListto make ordered folding an explicit contract (MAINT-08).SimpleSpecificationResolver, reject a field carrying both@Andand@Orwith a descriptive exception instead of silently picking And (MAINT-09).@Orunder class-level AND; first-position@Andunder class-level OR; permutation-equivalence assertions; direct unit tests forConjunction/Disjunction.combine.Acceptance criteria
@And+@Oron one field fails fast with a descriptive message.make testgreen.