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

@JsonCreator annotated factory method not used when wrapping value object #3210

Open
wimdeblauwe opened this issue Jul 14, 2021 · 0 comments

Comments

@wimdeblauwe
Copy link

I am using Jackson 2.12.3 and it seems that Jackson will sometimes take preference for a private constructor over a public static factory method that is annotated with @JsonCreator.

This example showcases the problem:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;

import java.io.IOException;

public class Test {
    public static void main(String[] args) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new ParameterNamesModule());
        ValueObject valueObject = objectMapper.readValue("{\"value\":\"ABC-123\"}", ValueObject.class);
        System.out.println("valueObject = " + valueObject);
        System.out.println("----");
        WrapperObject wrapperObject = objectMapper.readValue("{\"valueObject\":\"ABC-123\"}", WrapperObject.class);
        System.out.println("wrapperObject = " + wrapperObject);
    }

    public static class ValueObject {
        private final String value;

        private ValueObject(String value) {
            System.out.println("constructor: " + value);
            this.value = value;
        }

        @JsonCreator
        public static ValueObject of(String value) {
            System.out.println("factory: " + value);
            return new ValueObject(value);
        }

        public String getValue() {
            return value;
        }
    }

    public static class WrapperObject {
        private final ValueObject valueObject;

        @JsonCreator
        public WrapperObject(ValueObject valueObject) {
            this.valueObject = valueObject;
        }

        public ValueObject getValueObject() {
            return valueObject;
        }
    }
}

Running this (on Java 11) outputs:

factory: ABC-123
constructor: ABC-123
valueObject = be.fodjustitie.inventaris.inventarisbackend.Test$ValueObject@2a3b5b47
----
constructor: ABC-123
wrapperObject = be.fodjustitie.inventaris.inventarisbackend.Test$WrapperObject@799f10e1

So you can see when deserializing WrapperObject, the factory is not used which I would not expect given the factory method is annotated with @JsonCreator.

This might be related to #660 and/or #2135, not sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants