Skip to content

Fix #5742: prevent @JsonSetter(contentNulls) propagation into nested containers#5751

Open
dlwldnjs1009 wants to merge 2 commits intoFasterXML:3.xfrom
dlwldnjs1009:fix/5742-contentNulls-nested-propagation
Open

Fix #5742: prevent @JsonSetter(contentNulls) propagation into nested containers#5751
dlwldnjs1009 wants to merge 2 commits intoFasterXML:3.xfrom
dlwldnjs1009:fix/5742-contentNulls-nested-propagation

Conversation

@dlwldnjs1009
Copy link
Copy Markdown
Contributor

Summary

@JsonSetter(contentNulls = Nulls.FAIL) on nested container properties such as
List<List<String>> incorrectly rejects [[null]]. Only [null] (null
immediate content of the annotated container) should be rejected.

The root cause is that container deserializers pass the same BeanProperty into
nested content deserializer contextualization, so deeper container levels read
the outer property's annotation-level contentNulls.

Changes

  • Add _contentProperty() in StdDeserializer to create a derived
    BeanProperty view for nested content contextualization that strips only the
    outer property's explicit annotation-level contentNulls.
  • Recompute nested contentNulls from the nested content type's
    ConfigOverride or global default.
  • Add _ContentBeanProperty, a lightweight delegating wrapper that preserves the
    original property identity (name/member/type) and overrides only metadata
    relevant to nested content-null handling.
  • Apply to the container deserializer paths covered by the reported reproduction
    and closely related nested-container cases: CollectionDeserializer,
    MapDeserializer, EnumMapDeserializer, and ObjectArrayDeserializer.

Properties without explicit @JsonSetter(contentNulls=...) retain existing
behavior, including ConfigOverride-only and global-default-only cases.

Scope & Known Gaps

This fix is intentionally scoped to the container deserializer paths involved in
the reported issue and closely related nested-container cases.

ReferenceTypeDeserializer (used by Optional, AtomicReference) and
MapEntryDeserializer follow the same general pattern, but are left for
follow-up to keep this PR focused on #5742.

Test plan

  • Field-based, creator-based, and Java record nested List tests
  • Nested Map<String, List<String>>, EnumMap, and String[][]
  • Regression: ConfigOverride-only and global-default-only behavior unchanged
  • Cross-config: annotation FAIL + global SKIP, annotation FAIL + ConfigOverride SKIP
  • ./mvnw clean verify passes

@github-actions
Copy link
Copy Markdown

🧪 Code Coverage Report

Metric Coverage Change
Instructions coverage 81.26% 📉 -0.020%
Branches branches 74.43% 📈 +0.020%

Coverage data generated from JaCoCo test results

@github-actions
Copy link
Copy Markdown

🧪 Code Coverage Report

Metric Coverage Change
Instructions coverage 81.27% 📉 -0.010%
Branches branches 74.44% 📈 +0.020%

Coverage data generated from JaCoCo test results

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants