jackson-databind icon indicating copy to clipboard operation
jackson-databind copied to clipboard

Null coercion with `@JsonSetter` does not work with `java.lang.Record`

Open cowtowncoder opened this issue 3 years ago • 2 comments

Looks like use of @JsonSetter(nulls=...) does not work with Records in 2.12.0.

Note that earlier report (#2970) turned out to be valid, but since I closed it earlier decided to file a separate one.

cowtowncoder avatar Dec 06 '20 23:12 cowtowncoder

Oh boy. This gets deeper and deeper. But long and short of this is that there IS one specific work-around: name your constructor parameters and linkage works. For example:

    record RecordWithNonNullDefs(List<String> names,Map<String, Integer> agesByNames)
    {
        @JsonCreator
        public RecordWithNonNullDefs(
            @JsonProperty("name") @JsonSetter(nulls=Nulls.AS_EMPTY) List<String> names,
            @JsonProperty("agesByNames") @JsonSetter(nulls=Nulls.FAIL) Map<String, Integer> agesByNames)
        {
            this.names = names;
            this.agesByNames = agesByNames;
        }
    }

Not pretty but works. I'll see if this can be fixed more generally but this is the workaround for now.

cowtowncoder avatar Dec 15 '20 05:12 cowtowncoder

Ok so the problem is as follows:

  1. During initial POJOPropertiesCollector scan, only explicitly-annotated constructor parameters are located (no attention paid to Creator (constructor/factory) methods themselves, linked to method/field accessors
  2. BasicBeanDescription is constructed
  3. BeanDeserializerFactory (and/or BasicDeserializerFactory) goes over Creator candidates, selects what to included, but does not (can not?) link CreatorProperty instances found using this method; only ones that were already located are

Now: there are couple of ways things could be improved. For example, either

  • Try to link not-explicitly-named properties from step (3), after the fact (also merging annotations)
  • Move Creator discovery to an earlier stage (POJOPropertiesCollector); at least explicitly located ones

of these, first option seems more likely for 2.x; second better overall (and hence for 3.x). But both are big enough changes that they probably should NOT be attempted for 2.12.x patch release; esp. since there are workarounds.

So marking this as 2.13, unlikely to be attempted for 2.12.x.

cowtowncoder avatar Dec 15 '20 21:12 cowtowncoder