Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deserialization of enums with enum values annotated with the same @JsonProperty value leads to InvalidDefinitionException: Multiple fields representing property #4606

Open
1 task done
noahzuch opened this issue Jul 1, 2024 · 6 comments
Labels
to-evaluate Issue that has been received but not yet evaluated

Comments

@noahzuch
Copy link

noahzuch commented Jul 1, 2024

Search before asking

  • I searched in the issues and found nothing similar.

Describe the bug

I'm using a thirdparty client that is deserializing json where in an enum multiple values are annotated with the same @JsonProperty value. When upgrading our dependencies from Jackson 2.15.4 to 2.17.1 (via Spring Boot 3.3.1) this API started failing with:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Multiple fields representing property ...

This issue seems similar to #4409, but is still present in 2.16.2.

Version Information

2.16.2 to 2.17.1

Reproduction

I modified the example in #4409 to use @JsonProperty

public static class Bug {
        public enum ColorMode {
            @JsonProperty("RGB")
            RGB,
            @JsonProperty("RGBA")
            RGBa,
            @JsonProperty("RGBA")
            RGBA
        }
        public ColorMode colorMode;
    }

    @Test
    public void enumFails() throws Exception {
        String json = "{ \"color_mode\": \"RGBA\"}";
        ObjectMapper mapper = new ObjectMapper();
        mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        Bug bug = mapper.readValue(json, Bug.class);
        System.out.println(bug.colorMode);
    }

Expected behavior

Whether or not the old behaviour is expected, i can not tell. All I know is that in 2.15.4 it seems like the last enum property with the given @JsonProperty is used. So when execution the code above, the value RGBA is printed in the console. When switching the order of RGBA und RGBa, then RGBa is printed.

The current behaviour in 2.16.2 up to 2.17.1 is an exception when deserializing saying:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Multiple fields representing property "RGBA": my.package.Temp$Bug$ColorMode#RGBA vs my.package.Temp$Bug$ColorMode#RGBa at [Source: REDACTED (StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION disabled); line: 1, column: 1]

Additional context

No response

@noahzuch noahzuch added the to-evaluate Issue that has been received but not yet evaluated label Jul 1, 2024
@noahzuch noahzuch changed the title Deserialization of enums with enumvalues annotated with the same @JsonProperty value leads to InvalidDefinitionException: Multiple fields representing property Deserialization of enums with enum values annotated with the same @JsonProperty value leads to InvalidDefinitionException: Multiple fields representing property Jul 1, 2024
@pjfanning
Copy link
Member

Why do you have @JsonProperty("RGBA") on 2 different enum values? How is Jackson supposed to decide between the 2 enum values when you say that the same JSON input maps to 2 different enum values?

@noahzuch
Copy link
Author

noahzuch commented Jul 1, 2024

The example above is not production code. We depend on a separate library internal to our company. There, they use this to serialize two enum values to the same string, I guess (I will report why they use this once I get an answer from them). Im not sure if the old behaviour is by design or just a coincidence. Nevertheless it is a breaking change to 2.15.4

@pjfanning
Copy link
Member

The new code seems more correct. We cannot deserialize properly if 2 enum values have the same text representation.
I guess you can still serialize with that set up but we are talking about deserialization.

My vote would be to keep the new code as is.

@cowtowncoder
Copy link
Member

I agree: there is a genuine conflict. While I can see why for serialization-only use case someone might want to have 2 enum choices serialize into same String, this is currently not supported; and I am not sure it could be like this, given that @JsonProperty also affects deserialization where ambiguity occurs.
Use of @JsonGetter("name") would be less ambiguous and perhaps workable, although I don't think it would avoid the exception currently.

@noahzuch
Copy link
Author

noahzuch commented Jul 2, 2024

A team member responsible for this internal library will comment here why they used this functionality exactly. From my point of view as the creator of this issue I am also happy with the current behaviour in 2.16.2 upwards.

@cowtowncoder
Copy link
Member

@noahzuch That would be interesting to hear about. And even if the new behavior were to remain, it is good there is a report for this change in case someone else is affected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
to-evaluate Issue that has been received but not yet evaluated
Projects
None yet
Development

No branches or pull requests

3 participants