Why is Jackson ignoring the @JsonCreator annotation in my autogenerated POJO Enum?

As usual, there is a very simple solution to my problem:

I have a JSON schema snippet that defines the following enum:

"title" : {
    "type": "string",
    "enum": ["Mr", "Miss", "Mrs", "Ms"],
    "description": "The person title"
 }

      

My company structure uses jsonschema2pojo and maven to create the required POJO ( Title

lives in Clazz

as Title

part Clazz

of the JSON schema - with clazz as the generated name - replace it with employee or customer or whatever you like):

Generated by POJO

@Generated("org.jsonschema2pojo")
public static enum Title {

    MR("Mr"),
    MISS("Miss"),
    MRS("Mrs"),
    MS("Ms");
    private final String value;
    private static Map<String, Clazz.Title> constants = new HashMap<String, Clazz.Title>();

    static {
        for (Clazz.Title c: values()) {
            constants.put(c.value, c);
        }
    }

    private Title(String value) {
        this.value = value;
    }

    @JsonValue
    @Override
    public String toString() {
        return this.value;
    }

    @JsonCreator
    public static Clazz.Title fromValue(String value) {
        Clazz.Title constant = constants.get(value);
        if (constant == null) {
            throw new IllegalArgumentException(value);
        } else {
            return constant;
        }
    }
}

      

When I run a request containing the following against it:

...
  "title" : "Mr",
...

      

I am getting this error thrown at me:

com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of com.example.foo.representations.jaxb.Clazz$Title from String value 'Mr': value not one of declared Enum instance names: [Mr, Miss, Mrs, Ms]  at [Source: org.apache.cxf.transport.http.AbstractHTTPDestination$1@1a372b7; line: 4, column: 3] (through reference chain: com.example.foo.representations.jaxb.MySchema["Clazz"]->com.example.foo.representations.jaxb.Clazz["title"])

      

Obviously "Mr" is in the Enum.

When debugging, I see it going through the following classes ( stack ):

findEnum():120, EnumResolver (com.fasterxml.jackson.databind.util)
deserialize():79, EnumDeserializer (com.fasterxml.jackson.databind.deser.std)

      

They seem to be interested in Enum keys (ie constants like " MR

" instead of " MR

"). I'm guessing the annotation @JsonCreator

is being ignored for some reason.

Any idea how I can fix this problem? Is there a config value that can be set anywhere that can cause this behavior? (I work on large projects, if I know what I need to look for, I can find the code base, maybe another developer "misconfigured" something somewhere ...) Or maybe the problem that Title

lives in Clazz

? Do I need to cast @JsonProperty

for a good grade? (If so, how exactly?)

We are using jackson-core, -nnotes and -databind 2.4.2.

Update . I tried this as a separate project with the following code and it worked flawlessly - which means there must be some setting that does not take the annotation into account ...

ObjectMapper mapper = new ObjectMapper(); // create once, reuse
Clazz value = mapper.readValue(new File("resources/data.json"), Clazz.class);

      

+3


source to share


1 answer


So it turned out that the following was done in our Spring configuration:

<bean id="mapper" class="com.example.foo.jaxb.links.JsonMapper" />
<!-- ... -->
       <jaxrs:providers>
           <bean id="jsonprovider"
                 class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider">
               <constructor-arg ref="mapper" />
               <constructor-arg>
                   <value></value>
               </constructor-arg>
           </bean>
       </jaxrs:providers>

      

Jsonmapper extends com.fasterxml.jackson.databind.ObjectMapper

and basically sets Jackson's settings to itself in its constructor. However, one thing that I missed in my despair was a bit of code:



// use JAXB annotations (only) 
setAnnotationIntrospector(new JaxbAnnotationIntrospector(
    com.fasterxml.jackson.databind.type.TypeFactory.defaultInstance()));

      

And that pretty much does what he says in tin seems to be: he doesn't let Jackson evaluate annotations @JsonCreator

and @JsonValue

. After the Jackson annotation suppressor disappeared, all is well.

I'd like to understand how this works, so if anyone has helpful links to docs / instructions / guides / books for Spring stuff or annotation suppression it would be greatly appreciated. But in the meantime, this fixes my problem. :)

+2


source







All Articles