Skip to content

@JsonValue ignores propertyInclusion rules for config overide #5380

@LSwiatek

Description

@LSwiatek

Search before asking

  • I searched in the issues and found nothing similar.

Describe the bug

During serialization of objects using @JsonValue , property inclusion rules are checked from config overide for target type of @JsonValue.
For example if global property inclusion is NON_EMPTY, and an overide for string is set to NON_NULL, and a object is using @JsonValue where the value would be an empty string,
then output json will not include this property

Version Information

2.16.2, 2.20.0

Reproduction

package com.oberthur.ldz.auxutils.mapper.jackson;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class JsonValueTest {

    record JsonValuePojo(String stringValue) {
        @JsonValue
        public String toString() {
            return stringValue;
        }
    }

    record WrapperPojo(JsonValuePojo jsonValuePojo) {
    }

    record StringPojo(String stringValue) {
    }

    private static ObjectMapper mapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_EMPTY);
        objectMapper.configOverride(String.class)
                .setIncludeAsProperty(JsonInclude.Value.construct(JsonInclude.Include.NON_NULL, JsonInclude.Include.NON_NULL));
        //pretty print
        objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
        return objectMapper;
    }

    @Test
    //this test fails
    void jsonValueShouldSerializeToEmptyString() throws JsonProcessingException {
        ObjectMapper objectMapper = mapper();
        String json = objectMapper.writeValueAsString(new WrapperPojo(new JsonValuePojo("")));
        Assertions.assertEquals("""
                {
                  "jsonValuePojo" : ""
                }""", json);
    }

    @Test
    void simplePojoShouldSerializeEmptyString() throws JsonProcessingException {
        ObjectMapper objectMapper = mapper();
        String json = objectMapper.writeValueAsString(new StringPojo(""));
        Assertions.assertEquals("""
                {
                  "stringValue" : ""
                }""", json);

    }
}

Expected behavior

@JsonValue should use the same serialization rules as target type

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    to-evaluateIssue that has been received but not yet evaluated

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions