Jackson deserializer not using JacksonXmlProperty localname when used with JsonPOJOBuilder
See original GitHub issueHello,
I’m currently developing a library to enable conversion between MSML with custom elements and Java’s POJOs. I have encountered several issues related to jackson (de)serialization in the last few weeks needing workarounds that I would prefer to avoid. I have already dug over issues there and tentative solutions before posting here.
This issue report concerns the JacksonXmlProperty annotation’s localname not used by Jackson Deserializer when JsonPOJOBuilder is also used. Ideally, jackson should be aware of the local name specified by this annotation when deserializing with the pojo builder annotation also used.
This issue occurs to me on the following code:
@Builder
@JacksonXmlRootElement(localName = "stats")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonDeserialize(builder = StatsQuery.StatsQueryBuilder.class)
public class StatsQuery {
@JacksonXmlProperty(localName = "queryid", isAttribute = true)
private String queryId;
@JacksonXmlProperty(localName = "list", isAttribute = true)
private String list;
@JacksonXmlProperty(localName = "reset", isAttribute = true)
@Builder.Default private Boolean reset = true;
@JsonPOJOBuilder(withPrefix = "")
public static class StatsQueryBuilder {
}
}
You can see there that the java field is using camelCase per conventions and the xml property are defined in downcase. The builder class need to be specified so I can have reset value set to true and not null as I use Lombok as a builder generator
Attempting a deserialization with the above code results in the following exception:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "queryid" (class StatsQuery$StatsQueryBuilder), not marked as ignorable (3 known properties: "queryId", "list", "reset"])
.
The problem seems to be that in this case of having @JsonPOJOBuilder, jackson uses java field names and not @JacksonXMLProperty as it should. This occurs for every fields of my project when the java name is different (or has a different case) than the property, which is the goal of having a local name attribute.
The temporary solution, I have found was to also set the JAXB annotation @JsonProperty(“queryid”) on the field. However you can easily see that mentioning 2 annotations with the same supposed goal is not a proper way of writing good code as the two annotations are coupled (modifying one causes modifying the other).
If you need more information, please tell me.
System information
Java version : 11 Jackson version : jackson-dataformat-xml@2.10.2 Woodstox : woodstox-core@6.0.3 Lombok : lombok@1.18.12
Issue Analytics
- State:
- Created 4 years ago
- Comments:20 (10 by maintainers)
Top GitHub Comments
FYI: I created a PR for lombok (rzwitserloot/lombok#2416 ) to also automatically copy
@JacksonXmlProperty
to the builder setter method (as it already does for@JsonProperty
). This would solve this issue at least for lombok users. I still suggest to document that Jackson does not consider those annotations on a setter method parameter.It would make to see if you can see something that matches. There are, for example:
@JsonNaming
from value class for builderso I am bit torn on exactly how to formulate RFE. It sounds like this would be more complicated than just associating class-annotations from value type to builder (which is relatively easier), and somehow tried to associate annotations on properties to help guide builder.
So I guess, yes, please file a
jackson-databind
request: it can be referring to@JsonProperty
(but mentioned@JacksonXmlProperty
as alias) since main mechanism would be about inclusion, naming.