Skip to content

JsonInclude.Include.NON_DEFAULT regression for Records with @JsonValue #5312

Description

@LSwiatek

Search before asking

  • I searched in the issues and found nothing similar.

Describe the bug

Classes which use @JsonValue
and use values which would result in empty string
and are used as fields in serializable Pojos,
and Object mapper is configured with Include.NON_DEFAULT
will result in different json values starting with version 2.18

Following test case will work fine in version 2.17.3, but will fail after upgrading to 2.18+

Note, this might be related to #4741 #4464

Version Information

2.18+

Reproduction

package com.example;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.cfg.MutableConfigOverride;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_DEFAULT;
import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;

public class JacksonTest {

    record StringValue(String value) {
        @Override
        @JsonValue
        public String value() {
            return value;
        }
    }
    record Pojo1(StringValue value) {
    }

    @JsonInclude(JsonInclude.Include.NON_DEFAULT)
    record Pojo2(StringValue value) {
    }


    record Pojo3(@JsonInclude(JsonInclude.Include.NON_DEFAULT) StringValue value) {
    }


    @Test
    void testSerialization() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(NON_DEFAULT);

        //might be relevant for analysis, but does not affect test outcome
        MutableConfigOverride objectStringConfigOverride = objectMapper.configOverride(String.class);
        objectStringConfigOverride.setIncludeAsProperty(JsonInclude.Value.construct(NON_NULL, NON_NULL));

        Assertions.assertAll(
                //FAIL on jackson 2.18.2 / 2.20.0
                () -> Assertions.assertEquals("{\"value\":\"\"}", objectMapper.writeValueAsString(new Pojo1(new StringValue("")))),
                //PASS
                () -> Assertions.assertEquals("{\"value\":\"\"}", objectMapper.writeValueAsString(new Pojo2(new StringValue("")))),
                //FAIL on jackson 2.18.2 / 2.20.0
                () -> Assertions.assertEquals("{\"value\":\"\"}", objectMapper.writeValueAsString(new Pojo3(new StringValue(""))))
        );
    }
}

Expected behavior

After serialization jackson should produce the same value

Additional context

No response

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

    3.1RecordIssue related to JDK17 java.lang.Record support

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions