Skip to content

Record component is not ignored when overriding accessor method #4005

Closed
@codingtim

Description

@codingtim

Since we moved from 2.14.2 to 2.15.2 we see different behavior for Records who override the accessor.

This record serializes to JSON

record Record3(@JsonProperty String a, @JsonIgnore String b){
    public String b(){
        return b;
    }
}

In version 2.14.2: {"a":"aValue"}
In version 2.15.2: {"a":"aValue","b":"bValue"}

If I so the same in a class:

static class Class3 {
    @JsonProperty
    private final String a;
    @JsonIgnore
    private final String b;

    public Class3(String a, String b) {
        this.a = a;
        this.b = b;
    }

    public String getB() {
        return b;
    }
}

In version 2.14.2: {"a":"aValue"}
In version 2.15.2: {"a":"aValue"}

Is there a reasoning why the class and record seem to behave differently?
The release note of version 2.15.0 do mention improved support for Records but this seems like a regression for us.
Our fix is marking the record accessor method with JsonIgnore.

Full test:

public class SerTest {

    record Record1(@JsonProperty String a, @JsonProperty String b) {
    }

    record Record2(@JsonProperty String a, @JsonIgnore String b) {
    }

    record Record3(@JsonProperty String a, @JsonIgnore String b) implements MyInt {
        public String b() {
            return b;
        }
    }

    interface MyInt {
        String b();
    }

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Test
    void testRecords() throws JsonProcessingException {
        Record1 record1 = new Record1("aValue", "bValue");
        Record2 record2 = new Record2("aValue", "bValue");
        Record3 record3 = new Record3("aValue", "bValue");
        String s1 = objectMapper.writeValueAsString(record1);
        String s2 = objectMapper.writeValueAsString(record2);
        String s3 = objectMapper.writeValueAsString(record3);
        Assertions.assertEquals("{\"a\":\"aValue\",\"b\":\"bValue\"}", s1);
        Assertions.assertEquals("{\"a\":\"aValue\"}", s2);
        //different behaviour from 2.14.2
        Assertions.assertEquals("{\"a\":\"aValue\",\"b\":\"bValue\"}", s3);
    }

    static class Class1 {
        @JsonProperty
        private final String a;
        @JsonProperty
        private final String b;

        public Class1(String a, String b) {
            this.a = a;
            this.b = b;
        }
    }

    static class Class2 {
        @JsonProperty
        private final String a;
        @JsonIgnore
        private final String b;

        public Class2(String a, String b) {
            this.a = a;
            this.b = b;
        }
    }

    static class Class3 {
        @JsonProperty
        private final String a;
        @JsonIgnore
        private final String b;

        public Class3(String a, String b) {
            this.a = a;
            this.b = b;
        }

        public String getB() {
            return b;
        }
    }

    @Test
    void testClasses() throws JsonProcessingException {
        Class1 class1 = new Class1("aValue", "bValue");
        Class2 class2 = new Class2("aValue", "bValue");
        Class3 class3 = new Class3("aValue", "bValue");
        String s1 = objectMapper.writeValueAsString(class1);
        String s2 = objectMapper.writeValueAsString(class2);
        String s3 = objectMapper.writeValueAsString(class3);
        Assertions.assertEquals("{\"a\":\"aValue\",\"b\":\"bValue\"}", s1);
        Assertions.assertEquals("{\"a\":\"aValue\"}", s2);
        Assertions.assertEquals("{\"a\":\"aValue\"}", s3);
    }

}

Metadata

Metadata

Assignees

No one assigned

    Labels

    RecordIssue related to JDK17 java.lang.Record supportduplicateDuplicate of an existing (usually earlier) issue

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions