kotshi: Non constructor parameters properties are ignored
Hi, I’m migrating an app from moshi-kotlin to kotshi, until I got an unexpected KotlinNPE caused by JSON parsing error.
The expected property was a var
in my @JsonSerializable
data class, that is intentionally not part of the constructor, because I don’t want its value to be part of the data class stuff like equals, hashCode, copy…
Here’s a digest example snippet:
@JsonSerializable
data class MyUser(
val id: String,
@Json(name = "firstname")
val firstName: String,
@Json(name = "lastname")
val lastName: String?
) {
@Json(name = "support_tickets")
@Ignore // Used for Android Arch Room
var supportTickets: List<SupportTicket>? = null
}
In the example above, if there’s a list with the support_tickets
expected key in the input JSON, it’ll be ignored andsupportTickets
will still be null, because version 0.3.0-beta1 unfortunately doesn’t generate any code for properties not in the default constructor.
When I was using moshi-kotlin with the gigantic kotlin-reflect library, there was no bug in this case, it went as expected with no KNPE for when the value was expected.
Hope my bug report is clear and you can find a path to a proper fix! 😃
Have a nice day!
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 15 (15 by maintainers)
Commits related to this issue
- Update the readme to clarify some limitations This change was requested in #30 — committed to ansman/kotshi by ansman 7 years ago
So, to clarify: my use case is to ignore property with Room, while still getting it from the JSON.
Your second constructor trick worked perfectly, and while I had to add a bit more boilerplate for the constructor delegation considering the high number of parameters, it enabled me to separate the Room annotations (
@Embedded
) that are seen in the main constructor from the Kotshi/Moshi ones (@Json(name= "…")
) that are seen in the secondary one. It makes it clearer what is persisted in DB and what is got from the remote API.Thanks for your help, again!
I’m closing this issue now that this limitation is documented.
@LouisCAD I would prefer to not have support for that unless there is a very compelling argument. I don’t think we should consider properties declared outside the primary constructor to be a part of that class. This is similar to how Kotlin treats data classes (it doesn’t include those properties in
hashCode
,equals
ortoString
) which to me means that Kotlin’s intentions are for those properties to be considered computed or cached.One “hack” you could potentially use is to have two constructors like this:
Generated adapter: