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

@JsonProperty on enum values is silently ignored with @JsonFormat. Instead it should throw an exception.

Open kreiger opened this issue 2 months ago • 1 comments

Is your feature request related to a problem? Please describe.

Today i ran into a problem where i had an enum with values annotated with @JsonProperty, something like e.g:

enum MyEnum {
    @JsonProperty("1")
    FOO,
    @JsonProperty("42")
    BAR
}

I wanted it to be serialized as a number (1 or 42) instead of a string ("1" or "42").

So i annotated it with @JsonFormat:

@JsonFormat(shape = NUMBER)
enum MyEnum {
    ...
}

And was surprised when in my test MyEnum.BAR serialized to 1, using ordinal(), and the @JsonProperty was silently ignored.

This means that @JsonProperty on enums is incompatible with @JsonFormat.

Describe the solution you'd like

I found a closed feature request asking for this to work as expected: https://github.com/FasterXML/jackson-databind/issues/3580#issuecomment-1504230457

It's apparently up in the air whether this can be implemented, although it seems to not be completely dismissed as a possibility in the future.

In the meantime, can i please suggest that Jackson should throw e.g. a JsonMappingException instead of silently ignoring the @JsonProperty when @JsonFormat overrides it in this case?

Usage example

@JsonFormat(shape = NUMBER)
enum MyEnum {
    @JsonProperty("1")
    FOO
}

throws

Problem with definition of [AnnotedClass MyEnum]: @JsonProperty on enum values incompatible with @JsonFormat
com.fasterxml.jackson.databind.JsonMappingException: Problem with definition of [AnnotedClass MyEnum]: @JsonProperty on enum values incompatible with @JsonFormat
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:...)
    ...
Caused by: ...
    ...
    at com.fasterxml.jackson.databind.ser.BasicSerializerFactory.findSerializerByAnnotations(...)
    ...

Additional context

I know that i can annotate a method with @JsonValue like so:

enum MyEnum {
    FOO(1),
    BAR(42),
    ;

    final int value;

    MyEnum(int value) {
        this.value = value;
    }
    
    @JsonValue
    int value() {
        return value;
    }
}

But the int is not used in my code, just in the serialized JSON, so this is noisier, and it seemed to me that using JsonFormat should "just work" as i expected. 🙂

kreiger avatar Oct 02 '25 15:10 kreiger

Ok. I am not opposed to actually making this work (i.e. original usage to be supported), but that'd need to come as contribution.

As to failing the combination... sounds reasonable although cross-annotation validation is not really done for many (any?) other cases.

Note on #3580: I guess deserialization in particular would be challenging, wrt @JsonProperty only allowing Strings. But with @JsonFormat I can see why that'd make logical sense.

cowtowncoder avatar Oct 03 '25 03:10 cowtowncoder