Skip to content

[Data Integrity] Recursively snapshot structured ChangeRecord values #227

Description

@seonghobae

Buyer-visible integrity gap

Protected develop@622e5e6c3d534f230c390f10e3832efadfc01825 makes etl-service ChangeRecord top-level before / after / pk maps unmodifiable and snapshots those map objects, but nested JSON-shaped Map and List values remain aliased to caller-owned mutable objects. A connector or adapter can therefore observe a different normalized record after construction if an upstream caller mutates a nested object/array, contradicting the class-level promise that callers cannot mutate a record after it enters the connector pipeline.

This matters for plugin/connector determinism, equality/hash stability, replay/audit reasoning, and cross-service handoff integrity. The live Debezium/ObjectMapper path represents nested JSON objects/arrays as ordinary Java maps/lists, so this is a real supported data shape rather than an exotic arbitrary-object case.

Scope

Keep the repair bounded to etl-service ChangeRecord and focused tests. Do not modify active CDC CanonicalChangeRecord PR #222, connector registry work, provider implementations, database migrations, or serialization contracts.

Test-first acceptance

  1. Add a failing regression first using nested mutable LinkedHashMap and ArrayList values inside after (and, where useful, before/pk).
  2. Prove both mutation paths fail closed from the caller perspective:
    • mutating the original nested containers after construction cannot change the record;
    • nested containers reachable through getters are unmodifiable.
  3. Preserve nested null values and list elements.
  4. Preserve current scalar/object identity semantics for non-container values; do not pretend arbitrary mutable third-party objects can be cloned safely.
  5. Implement the narrowest recursive snapshot for JSON-shaped Map<?, ?> and List<?> containers, with beginner-readable Javadocs explaining the boundary.
  6. Run focused and full applicable tests and keep the PR Draft until shared literal-source, scanner-completeness, non-vacuous coverage, and independent-review gates are satisfied.

Non-goals

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions