-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deserializing Java record with @JsonUnwrapped annotation throws exception "can not set final" #3726
Comments
@cowtowncoder is there any updates on this? |
@Taz03 come on - your comments go to lots of people. Do you really need to spam everyone every 3 hours? |
you can customize a deserilaizer @JsonDeserialize(using = TestDeserializer.class)
public record TestRecord(String name, @JsonUnwrapped Address address) {}
static class TestDeserializer extends JsonDeserializer<TestRecord> {
@Override
public TestRecord deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException, JacksonException {
JsonNode node = jsonParser.getCodec().readTree(jsonParser);
String name = node.get("name").asText();
String city = node.get("city").asText();
String state = node.get("state").asText();
return new TestRecord(name, new Address(city, state));
}
} ObjectMapper objectMapper = new ObjectMapper();
String json = "{\"name\":\"Bob\",\"city\":\"New York\",\"state\":\"NY\"}";
System.out.println(objectMapper.readValue(json, TestRecord.class));
// TestRecord[name=Bob, address=Address[city=New York, state=NY]] Or, use public record TestRecord(String name, @JsonUnwrapped @JsonProperty(access = Access.READ_ONLY) Address address) {
@JsonCreator
public TestRecord(@JsonProperty("name") String name, @JsonProperty("city") String city,
@JsonProperty("state") String state) {
this(name, new Address(city, state));
}
} ObjectMapper objectMapper = new ObjectMapper();
String json = "{\"name\":\"Bob\",\"city\":\"New York\",\"state\":\"NY\"}";
System.out.println(objectMapper.readValue(json, TestRecord.class));
// TestRecord[name=Bob, address=Address[city=New York, state=NY]] |
As I spent quite some time to find a solution that fits my case, it's not more than right to share it here. This is similar to what I ended up with, based on the example record above: public record TestRecord(
String name,
@JsonUnwrapped Address address
) {
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public TestRecord(JsonNode node) {
this(
ObjectMapperHolder.getObjectMapper().convertValue(node.get("name"), String.class),
ObjectMapperHolder.getObjectMapper().convertValue(node, Address.class)
);
}
} |
Actually there might be way forward for this, see #4271. |
Just use builder as deserializer will fix this.
|
I'm attempting to deserialize JSON into a simple Java record where one of the members, a simple POJO, is annotated as
@JsonUnwrapped
.If I attempt to deserialize the JSON string
{"name":"Bob","city":"New York","state":"NY"}
, I get the exception:Version information
Tested both 2.13.2 and 2.14.1 - same problem with both versions.
To Reproduce
This uses JDK17 multiline string but trivial to replace with escaped string.
Additional context
If I change TestRecord to a plain Java class, it works fine.
I've tried using the annotations
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
and annotating all fields with@JsonProperty
to no avail.The text was updated successfully, but these errors were encountered: