Jackson-databind: Allow overriding builder's "withPrefix" with new `@JsonDeserialize` property

Created on 15 Feb 2020  路  5Comments  路  Source: FasterXML/jackson-databind

It would be nice to be able to configure the builder method name prefix Jackson uses either globally through a configuration on ObjectMapper or through the @JsonDeserialize annotation itself. I'm currently using Lombok to generate my builders for me and to make it work nicely with Jackson I have to write boilerplate code, which is the whole point of lombok.

The Problem

Currently, in order to use Jackson and lombok in tandem, I have to write a model class like this:

@Builder
@JsonDeserialize(builder = Model.ModelBuilder.class)
public class Model {

    /** various properties */

    @JsonPOJOBuilder(withPrefix = "")
    public static class ModelBuilder {
    }
}

The issue becomes even worse if using the @SuperBuilder annotation:

@SuperBuilder
@JsonDeserialize(builder = Model.ModelBuilderImpl.class)
public class Model extends AbstractModel {

    /** various properties */

    @JsonPOJOBuilder(withPrefix = "")
    protected static final class ModelBuilderImpl extends Model.ModelBuilder<Model, Model.ModelBuilderImpl> {
    }
}

There's also a blurb about the workaround in Lombok's own documentation.

Related issue: https://github.com/FasterXML/jackson-databind/issues/1997

Global Config

One way to fix it would be to allow this to be configured globally on ObjectMapper like:

objectMapper.configure(DeserializationFeature.POJO_BUILDER_PREFIX, "");

JsonDeserialize Property

Another solution would be to allow it to be set on the @JsonDeserialize annotation itself, like:

@JsonDeserialize(builder = Model.ModelBuilder.class, withBuilderPrefix = "")

Personally, I prefer option 2.

2.13 builder-related

All 5 comments

Sounds like a reasonable idea, and I think I know the mechanism it should use (since I prefer not adding one-off configuration methods if at all possible: "config overrides".
This could even allow per-class non-annotation-based override, possibly.

I don't know which version this would go in -- 2.11 is not yet out, but not sure I have time to add it there, as I am hoping to wrap it up. But this could probably work out nicely for 2.12.

FWIW the Lombok team have implemented a @Jacksonized annotation for making Lombok models play nicely with Jackson.

@kennethjor Interesting. Thank you for sharing!

Ok, with #2800, there now IS a way to, I think, configure builder-"with" prefix, using new AccessNamingStrategy (and provider). And in fact DefaultAccessorNamingStrategy allows configuration, so something like:

    ObjectMapper mapper = JsonMapper.builder()
                .accessorNaming(new DefaultAccessorNamingStrategy.Provider()
                        .withBuilderPrefix("") // no prefix
// or                       .withBuilderPrefix("With") //  would expect 'WithX()' etc
                )
                .build();

or, if you want something more complicated (multiple prefixes, or different naming convention),
just implement strategy yourself (and configure with Provider that constructs instances).

Added a test to verify that case above (no/empty prefix) works as expected.

But I think I will leave this open as addition of an annotation in @JsonDeserialize does seem like a good idea, if it can be pulled off.

Was this page helpful?
0 / 5 - 0 ratings