Serializing collections with Jackson in Scala and renaming the nested element

This is a workaround for XML collection duplicated element names that I was fixing recently.

We use case classes in Scala and the Jackson library for XML serialization. We have a class that has a list of some nested class. When serializing it, we would like to name the nested element properly.

We start with these classes:

When we try to serialize it, we’ll get something like this:

You can see that we have Base -> People -> People instead of Base -> People -> Person. We can try to fix it with regular annotations:

It now serializes correctly. However, when you try to deserialize it, you get the following exception:

This fails because we use JacksonXmlProperty to rename the property and this gets handled incorrectly.

The issue is with how Scala implements case classes. Fields are always stored as private fields with getters (and setters if you use var), and the annotations are propagated to the constructor parameters.

My way of fixing it was the following:

  • Do not propagate annotations to the constructor
  • Create another constructor that has a different signature that the default one
  • Mark the constructor as @JsonCreator

This way, Jackson creates the object with default values using the new constructor, and then sets the fields with reflection. So, this is how the code should look like:

You could go with some different constructor if needed (like a parameterless one and pass nulls explicitly).

This works with Jackson 2.13.0.