jackson-databind
jackson-databind copied to clipboard
Allow overriding builder's "withPrefix" with new `@JsonDeserialize` property
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.
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.