-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Describe the bug
When using @JsonIdentityInfo, Jackson deserializes an immutable class fine but the equivalent record does not.
Version information
Jackson 2.13.0
To Reproduce
I have a simple immutable class defined as follows:
@JsonSerialize
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "name", scope = ProjectResource.class)
public static final class ProjectResource {
private final String name;
private final String path;
@JsonCreator
public ProjectResource(String name, String path) {
this.name = name;
this.path = path;
}
public String name() {
return name;
}
public String path() {
return path;
}
//equals, hashCode, toString
}
The equivalent record is as follows:
@JsonSerialize
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "name", scope = ProjectResource.class)
public record ProjectResource(String name, String path) {
@JsonCreator
public ProjectResource {
}
}
The XML being deserialized is the following:
<?xml version='1.1' encoding='UTF-8'?>
<project>
...
<resources>
<resources>
<name>beevillage.ogg</name>
<path>resources\1594389476\beevillage.ogg</path>
</resources>
</resources>
...
</project>
Finally, I have the following mapper (building with -parameters):
var module = new JacksonXmlModule();
module.addDeserializer(Color.class, new ColorDeserializer());
var xmlMapper = new XmlMapper(module);
xmlMapper.registerModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES));
xmlMapper.registerModule(new Jdk8Module());
var builder = xmlMapper.readValue(Files.readAllBytes(projectXml), ProjectBuilder.class);
return builder.build(projectFile, projectXml);
When I deserialize the XML to the first class it works fine, but when I do so to the second class I get the following error:
Can not set final java.lang.String field com.opengg.loader.Project$ProjectResource.name to java.lang.String
Maybe I'm doing something wrong, but my understanding of the record constructor syntax is that it generates the constructor in the same format as the immutable class, including any annotations. If the two classes are identical, I don't see a reason why the deserializer would be unable to use the constructor in the record case but have it work fine in the class case.
EDIT:
This seems to be related to #3297.