Skip to content

[WP1] Starter silently overrides every repository base class (data-loss risk) #191

Open

Description

@shihyuho

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

Work package WP1 · findings: COR-01 · worst severity: high · 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-01 — repositoryBaseClassCustomizer silently overrides the repository base class of every JPA repository (correctness, high)

  • File: starter/src/main/java/tw/com/softleader/data/jpa/spec/starter/autoconfigure/SpecMapperAutoConfiguration.java:131 (repositoryBaseClassCustomizer)
  • Evidence: the customizer calls factory.setRepositoryBaseClass(properties.getRepositoryBaseClass()) unconditionally on every JpaRepositoryFactoryBean. Spring Data applies a user's @EnableJpaRepositories(repositoryBaseClass = …) before running customizers, so the starter always wins — recorded only at DEBUG level.
  • Failure scenario: a consumer whose repositories use a soft-delete base class adds the starter; delete() silently reverts to SimpleJpaRepository's hard delete → physical data loss.

Design decision needed

The fix direction decides the starter's public contract, so it is maintainer-owned:

  • (a) Property-gated: register the customizer only when spec.mapper.repository-base-class is explicitly set. Stops the silent clobber, but breaks the starter's out-of-box base-class installation (QueryBySpecExecutor repositories would no longer get an implementation without configuration).
  • (b) Detect-and-skip: detect a pre-configured non-default base class and skip with a WARN. Preserves out-of-box behavior, but JpaRepositoryFactoryBean exposes no getter for the configured base class — detection needs a mechanism (e.g. reading the repository configuration source), which is itself a design choice.

Once the direction is decided, add a Plan section here and swap status: pending-design-work for status: ready-for-agent — work authorization travels with spec completeness.

Acceptance criteria (target)

  • A consumer that sets @EnableJpaRepositories(repositoryBaseClass = …) keeps its base class, or the conflict is surfaced loudly (WARN/fail per the chosen policy) — the silent hard-delete scenario no longer reproduces.
  • Regression: make test green.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions