jackson-module-kotlin
jackson-module-kotlin copied to clipboard
Deserialization of lists is lost under certain terminal node conditions
Describe the bug Deserialization of lists is lost under certain conditions. When I change the terminal nodes to have fake key names, the full structure is returned with those terminal nodes having null values. When I change the terminal nodes to reference real keys in the xml, the list is not maintained and instead returns the last entry that makes up the list with the correct terminal values.
To Reproduce
Small subset of xml data
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<feed xml:base="http://data.treasury.gov/Feed.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
<title type="text">DailyTreasuryYieldCurveRateData</title>
<id>http://data.treasury.gov/feed.svc/DailyTreasuryYieldCurveRateData</id>
<updated>2020-05-08T22:36:11Z</updated>
<link rel="self" title="DailyTreasuryYieldCurveRateData" href="DailyTreasuryYieldCurveRateData" />
<entry>
<id>http://data.treasury.gov/Feed.svc/DailyTreasuryYieldCurveRateData(1)</id>
<title type="text"></title>
<updated>2020-05-08T22:36:11Z</updated>
<author>
<name />
</author>
<link rel="edit" title="DailyTreasuryYieldCurveRateDatum" href="DailyTreasuryYieldCurveRateData(1)" />
<category term="TreasuryDataWarehouseModel.DailyTreasuryYieldCurveRateDatum" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<content type="application/xml">
<m:properties>
<d:Id m:type="Edm.Int32">1</d:Id>
<d:NEW_DATE m:type="Edm.DateTime">1997-01-02T00:00:00</d:NEW_DATE>
<d:BC_1MONTH m:type="Edm.Double" m:null="true" />
<d:BC_2MONTH m:type="Edm.Double" m:null="true" />
<d:BC_3MONTH m:type="Edm.Double">5.190000057220459</d:BC_3MONTH>
<d:BC_6MONTH m:type="Edm.Double">5.3499999046325684</d:BC_6MONTH>
<d:BC_1YEAR m:type="Edm.Double">5.630000114440918</d:BC_1YEAR>
<d:BC_2YEAR m:type="Edm.Double">5.96999979019165</d:BC_2YEAR>
<d:BC_3YEAR m:type="Edm.Double">6.130000114440918</d:BC_3YEAR>
<d:BC_5YEAR m:type="Edm.Double">6.3000001907348633</d:BC_5YEAR>
<d:BC_7YEAR m:type="Edm.Double">6.4499998092651367</d:BC_7YEAR>
<d:BC_10YEAR m:type="Edm.Double">6.5399999618530273</d:BC_10YEAR>
<d:BC_20YEAR m:type="Edm.Double">6.8499999046325684</d:BC_20YEAR>
<d:BC_30YEAR m:type="Edm.Double">6.75</d:BC_30YEAR>
<d:BC_30YEARDISPLAY m:type="Edm.Double">0</d:BC_30YEARDISPLAY>
</m:properties>
</content>
</entry>
<entry>
<id>http://data.treasury.gov/Feed.svc/DailyTreasuryYieldCurveRateData(2)</id>
<title type="text"></title>
<updated>2020-05-08T22:36:11Z</updated>
<author>
<name />
</author>
<link rel="edit" title="DailyTreasuryYieldCurveRateDatum" href="DailyTreasuryYieldCurveRateData(2)" />
<category term="TreasuryDataWarehouseModel.DailyTreasuryYieldCurveRateDatum" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<content type="application/xml">
<m:properties>
<d:Id m:type="Edm.Int32">2</d:Id>
<d:NEW_DATE m:type="Edm.DateTime">1996-12-31T00:00:00</d:NEW_DATE>
<d:BC_1MONTH m:type="Edm.Double" m:null="true" />
<d:BC_2MONTH m:type="Edm.Double" m:null="true" />
<d:BC_3MONTH m:type="Edm.Double">5.2100000381469727</d:BC_3MONTH>
<d:BC_6MONTH m:type="Edm.Double">5.3299999237060547</d:BC_6MONTH>
<d:BC_1YEAR m:type="Edm.Double">5.5100002288818359</d:BC_1YEAR>
<d:BC_2YEAR m:type="Edm.Double">5.880000114440918</d:BC_2YEAR>
<d:BC_3YEAR m:type="Edm.Double">6.0399999618530273</d:BC_3YEAR>
<d:BC_5YEAR m:type="Edm.Double">6.2100000381469727</d:BC_5YEAR>
<d:BC_7YEAR m:type="Edm.Double">6.3400001525878906</d:BC_7YEAR>
<d:BC_10YEAR m:type="Edm.Double">6.429999828338623</d:BC_10YEAR>
<d:BC_20YEAR m:type="Edm.Double">6.7300000190734863</d:BC_20YEAR>
<d:BC_30YEAR m:type="Edm.Double">6.6500000953674316</d:BC_30YEAR>
<d:BC_30YEARDISPLAY m:type="Edm.Double">0</d:BC_30YEARDISPLAY>
</m:properties>
</content>
</entry>
...
</feed>
With the following data classes I receive a response like the following:
Feed(entry=[...,Entry(id=http://data.treasury.gov/Feed.svc/DailyTreasuryYieldCurveRateData(7591), updated=2020-05-08T22:36:11Z, content=Content(properties=Properties(newDate=null, oneMonth=null))), Entry(id=http://data.treasury.gov/Feed.svc/DailyTreasuryYieldCurveRateData(7592), updated=2020-05-08T22:36:11Z, content=Content(properties=Properties(newDate=null, oneMonth=null))),
Entry(id=http://data.treasury.gov/Feed.svc/DailyTreasuryYieldCurveRateData(7593), updated=2020-05-08T22:36:11Z, content=Content(properties=Properties(newDate=null, oneMonth=null))), Entry(id=http://data.treasury.gov/Feed.svc/DailyTreasuryYieldCurveRateData(7594), updated=2020-05-08T22:36:11Z, content=Content(properties=Properties(newDate=null, oneMonth=null))),
Entry(id=http://data.treasury.gov/Feed.svc/DailyTreasuryYieldCurveRateData(7595), updated=2020-05-08T22:36:11Z, content=Content(properties=Properties(newDate=null, oneMonth=null))), Entry(id=http://data.treasury.gov/Feed.svc/DailyTreasuryYieldCurveRateData(7596), updated=2020-05-08T22:36:11Z, content=Content(properties=Properties(newDate=null, oneMonth=null)))])
data class Properties(
@JacksonXmlProperty(localName = "NEW_DATE_FAKE")
var newDate: String?,
@JacksonXmlProperty(localName = "BC_1MONTH_FAKE")
var oneMonth: String?
)
data class Content(
var properties: Properties
)
data class Entry(
var id: String,
var updated: String,
var content: Content
)
@JacksonXmlRootElement(namespace = "http://www.w3.org/2005/Atom", localName = "feed")
data class Feed(
@JacksonXmlElementWrapper(useWrapping = false)
var entry: List<Entry>
)
Expected behavior Changing the above Properties data class to the following, I would expect to see the the correct parsed structure to return. Instead the entry now only contains the last entry in the list. Notice though that the terminal nodes are parsed correctly.
data class Properties(
@JacksonXmlProperty(localName = "NEW_DATE")
var newDate: String?,
@JacksonXmlProperty(localName = "BC_1MONTH")
var oneMonth: String?
)
Feed(entry=[Entry(id=http://data.treasury.gov/Feed.svc/DailyTreasuryYieldCurveRateData(7596), updated=2020-05-08T22:36:11Z, content=Content(properties=Properties(newDate=2020-05-08T00:00:00, oneMonth=0.1)))])
Versions Kotlin:1.3.61 Jackson-module-kotlin:2.9.7 and 2.11.0 Jackson-databind: 2.9.7 and 2.11.0
Additional context I'm not really sure if this should be posted here or in one of the core jackson libraries.
Quick note: if it would be possible to reproduce this with java-only (by translating into similar pojo classes), it'd be easier to resolve, challenge being that XML format module is quite different from basic json handling and this problem is almost certainly specific to that module. But it might not be related to Kotlin handling.
Practical challenge being that neither Kotlin module nor XML format module have dependency to each other (even test dependency), so reproduction as-is could not be used for automated tests.