Skip to content

[WP6] Starter auto-configuration robustness (fluent null-spec, BPP early-init, ordering, API parity) #195

Open

Description

@shihyuho

此內容由 AI 產生(specification-mapper 全庫審查 2026-07-16.執行圖)。

Work package WP6 · findings: COR-13, COR-12, MAINT-02, MAINT-05 · 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-13 — Fluent findBySpec throws IllegalArgumentException for null or empty criteria, unlike every sibling method (correctness, medium)

  • File: starter/src/main/java/tw/com/softleader/data/jpa/spec/starter/repository/support/QueryBySpecExecutorAdapter.java:116
  • Evidence: the fluent overload passes mapper.toSpec(spec, domainClass) straight to findBy; empty criteria map to a null Specification and SimpleJpaRepository.findBy asserts non-null, while findBySpec(...)/findBySpec(..., pageable) tolerate null and return all rows.
  • Failure scenario: an empty search form submitted through the fluent projection/paging API → opaque 500.

COR-12 — BeanPostProcessor declared as non-static @Bean forces early instantiation of all RepositoryFactoryCustomizer beans (correctness, medium)

  • File: starter/src/main/java/tw/com/softleader/data/jpa/spec/starter/autoconfigure/SpecMapperAutoConfiguration.java:116
  • Evidence: jpaRepositoryFactoryBeanPostProcessor(List<RepositoryFactoryCustomizer>) is an instance @Bean method with an eager List injection — every customizer bean and its dependencies are instantiated at BPP-registration time, dropping proxying/@Transactional on those dependencies.

MAINT-02 — Auto-configuration lacks @AutoConfiguration/@AutoConfigureAfter; ordering rests on alphabetical FQCN sort (maintainability, medium)

  • File: starter/src/main/java/tw/com/softleader/data/jpa/spec/starter/autoconfigure/SpecMapperAutoConfiguration.java:111
  • Evidence: the class is a plain @Configuration; @ConditionalOnBean(JpaRepositoryFactoryBean.class) only evaluates correctly because the class name happens to sort after Spring Data's auto-configuration.

MAINT-05 — QueryBySpecExecutor lacks counterparts for JpaSpecificationExecutor's delete(spec) and findAll(spec, countSpec, pageable) (maintainability, low)

  • File: starter/src/main/java/tw/com/softleader/data/jpa/spec/starter/repository/QueryBySpecExecutor.java:44
  • Note: the countSpec overload was deliberately removed in PR Fix api cross 3.x #127 for cross-Boot-3.x compilation compatibility — do not blindly reintroduce it.

Plan

  1. COR-13: in the fluent findBySpec, substitute an unrestricted Specification (e.g. (root, query, cb) -> null) when toSpec yields null, matching sibling semantics (empty criteria = no filtering).
  2. COR-12: make the BPP @Bean method static and inject customizers lazily (ObjectProvider<RepositoryFactoryCustomizer>, resolved at post-process time).
  3. MAINT-02: convert the class to @AutoConfiguration(after = JpaRepositoriesAutoConfiguration.class), keeping the AutoConfiguration.imports registration consistent.
  4. MAINT-05: add deleteBySpec(Object spec) delegating to delete(Specification); document in Javadoc why the countSpec overload is intentionally absent (PR Fix api cross 3.x #127 cross-version constraint). (The join/fetch-POJO delete edge case is WP3's COR-08, not this package.)
  5. Tests: empty-criteria fluent query returns all rows; deleteBySpec deletes matching rows; a context test asserting the auto-configuration ordering annotation is in place.

Acceptance criteria

  • An empty form through the fluent API returns results instead of a 500.
  • Customizer beans and their dependencies are no longer force-initialized at BPP registration.
  • New tests from step 5 pass; regression: make test green.

Metadata

Metadata

Assignees

No one assigned

    Labels

    status: ready-for-agentFully specified and ready for an autonomous AFK agent to implementtype: bugSomething isn't working

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions