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

Cannot use both JsonCreator.Mode.DELEGATING and JsonCreator.Mode.PROPERTIES static creator factory methods for Enums #3566

Closed
andrewbents opened this issue Aug 5, 2022 · 1 comment · Fixed by #3851
Labels
enum Related to handling of Enum values

Comments

@andrewbents
Copy link

Describe the bug
When Enum has two factory methods, one with JsonCreator.Mode.DELEGATING and the other with JsonCreator.Mode.PROPERTIES, only the latter works. Deserialization that is supposed to target the DELEGATING one fails with com.fasterxml.jackson.databind.exc.MismatchedInputException.
Note that the same setup for a POJO works just fine.

Version information
2.13.3

To Reproduce

class TestCases {
    @Test
    void testClass() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        Assertions.assertEquals(new AClass("someName"), objectMapper.readValue("{ \"name\": \"someName\" }", AClass.class));
        Assertions.assertEquals(new AClass("someName"), objectMapper.readValue("\"someName\"", AClass.class));
    }

    @Test
    void testEnum() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        Assertions.assertEquals(AEnum.A, objectMapper.readValue("{ \"type\": \"AType\" }", AEnum.class));
        Assertions.assertEquals(AEnum.A, objectMapper.readValue("\"AType\"", AEnum.class)); // this line fails
    }
}

class AClass {
    private final String name;

    AClass(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
    public static AClass fromString(String name) {
        return new AClass(name);
    }

    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
    public static AClass create(@JsonProperty("name") String name) {
        return new AClass(name);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        AClass aClass = (AClass) o;
        return Objects.equals(name, aClass.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }
}

@JsonFormat(shape = JsonFormat.Shape.OBJECT)
enum AEnum {
    A("AType"),
    B("BType");

    private final String type;

    AEnum(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }

    @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
    public static AEnum fromString(String type) {
        return Arrays.stream(values())
                .filter(aEnum -> aEnum.type.equals(type))
                .findFirst()
                .orElseThrow();
    }

    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
    public static AEnum create(@JsonProperty("type") String type) {
        return fromString(type);
    }
}

The testClass passes, but testEnum fails with

com.fasterxml.jackson.databind.exc.MismatchedInputException: Input mismatch reading Enum `AEnum`: properties-based `@JsonCreator` ([method AEnum#fromString(java.lang.String)]) expects JSON Object (JsonToken.START_OBJECT), got JsonToken.VALUE_STRING

Also, you can remove the PROPERTIES factory method, and the DELEGATING method would work.

@andrewbents andrewbents added the to-evaluate Issue that has been received but not yet evaluated label Aug 5, 2022
@cowtowncoder cowtowncoder added the enum Related to handling of Enum values label Aug 5, 2022
@cowtowncoder cowtowncoder removed the to-evaluate Issue that has been received but not yet evaluated label Mar 28, 2023
@JooHyukKim
Copy link
Member

Can we add has-failing-test label here?

@cowtowncoder cowtowncoder changed the title Cannot use both JsonCreator.Mode.DELEGATING and JsonCreator.Mode.PROPERTIES static creator factory methods in Enum, but can for Class Cannot use both JsonCreator.Mode.DELEGATING and JsonCreator.Mode.PROPERTIES static creator factory methods for Enums Apr 1, 2023
cowtowncoder added a commit that referenced this issue Apr 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enum Related to handling of Enum values
Projects
None yet
3 participants