OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
21.82k stars 6.58k forks source link

[REQ] Don't use @JsonCreator in Java enums #2868

Open chrylis opened 5 years ago

chrylis commented 5 years ago

When applied to an enum property, Jackson's @JsonValue automatically provides a two-way translation that is likely to be more efficient than the generated fromValue. The @JsonCreator annotation is unnecessary and should be retired.

Applies to 3.3.4 and 4.0.0-beta3.

chrylis commented 5 years ago

This seems to have been mentioned in passing in #625. The fromValue is still needed for user code, but the reporter seems to misunderstand the contract on @JsonValue, which will automatically handle both directions without the need for a "from" mapping.

OLibutzki commented 3 years ago

Using @JsonCreator also leads to this exception with Jackson >= 2.11.x: https://github.com/FasterXML/jackson-module-kotlin/issues/336

So if you want to use @JsonCreator the mode needs to be set explicitly: @JsonCreator(mode = Mode.DELEGATING)

Michael-crazyman commented 3 years ago

@chrylis I am wondering are there any impacts/side-effects for @JacksonCreator? Our upstream services will generate the client code and push it to Jfrog, downstream services need to get the latest version of client code by adding a new maven dependency. However, there is a scenario that sometimes the upstream service will add some new enum values, but the enum have been used by the downstream service, so after the upstream service uses the new enum value and serialize it, the downstream services use the older version of the client code was not able to deserialize it correctly(may throw an exception with unrecognized enum value), but the client code is not interested in these new enums, so in a word, we want to avoid client throw exceptions and breaking the workflow, so I recommended that if we can return NULL/UNKNOWN when met Unrecognized enum value by utilizing @JsonCreator and a default factory method like this:

@Getter
public enum Players {

    KOBE_BRYANT,
    MICHAEL_JORDAN,
    KEVIN_DURANT,
    UNKNOWN,
    ;

    @JsonCreator
    public static Players fromString(String name) {
        return Arrays.stream(values()).filter(v -> v.name().equals(name)).findFirst().orElse(UNKNOWN);
    }
}

But it seems not a good solution, since we have to add extra code for every enum.Finally, I find a better solution:

spring:
  jackson:
    deserialization:
      READ_UNKNOWN_ENUM_VALUES_AS_NULL: true

I am wondering are there any better solutions for the enum de/serialize backward compatibility issue?

OleksandrYemolenko commented 1 year ago

@Michael-crazyman did you find any better solutions ?