Closed
Description
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);
}
}