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

Map key deserializerModifiers ignored #1445

Closed
alfonsobonso opened this issue Nov 8, 2016 · 4 comments
Closed

Map key deserializerModifiers ignored #1445

alfonsobonso opened this issue Nov 8, 2016 · 4 comments

Comments

@alfonsobonso
Copy link

We have a module that extends simple model to allow us to accept enum names in lower case in a fairly generic manner
Inside that we add the modifyKeyDeserializer

The incoming class (using immutables) is mapped to a guava immutable map.
Walking through the code:

com.fasterxml.jackson.datatype.guava.deser.ImmutableMapDeserializer.createContextual
calls DeserializationContext.findKeyDeserializer
calls DeserializerCache.findKeyDeserializer
calls BasicDeserializerFactory.createKeyDeserializer

which has the code:

        // the only non-standard thing is this:
        if (deser == null) {
            if (type.isEnumType()) {
                return _createEnumKeyDeserializer(ctxt, type);
            }
            deser = StdKeyDeserializers.findStringBasedKeyDeserializer(config, type);
        }

Since we are an enum type, it returns the value in the _createEnumKeyDeserializer, which is the standard enum deserializer.
Below that block is the check for the hasDeserializerModifiers, but since we have returned already, it is never called, so we can't override the behaviour.

Module fragment:

    setDeserializerModifier(new BeanDeserializerModifier() {
                @Override
                @SuppressWarnings("unchecked")
                public JsonDeserializer<Enum> modifyEnumDeserializer(
                        DeserializationConfig config,
                        final JavaType type,
                        BeanDescription beanDesc,
                        final JsonDeserializer<?> deserializer) {
                    return new JsonDeserializer<Enum>() {
                        @Override
                        public Enum deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
                            Class<? extends Enum> rawClass = (Class<Enum<?>>) type.getRawClass();
                            return Enum.valueOf(rawClass, jp.getValueAsString().toUpperCase());
                        }
                    };
                }

                @Override
                public KeyDeserializer modifyKeyDeserializer(
                        DeserializationConfig config,
                        JavaType type,
                        KeyDeserializer deserializer) {
                    if (!type.isEnumType()) {
                        return super.modifyKeyDeserializer(config, type, deserializer);
                    }
                    return new KeyDeserializer() {
                        @Override
                        @SuppressWarnings("unchecked")
                        public Object deserializeKey(String key, DeserializationContext ctxt)
                                throws IOException, JsonProcessingException {
                            Class<? extends Enum> rawClass = (Class<Enum<?>>) type.getRawClass();
                            return Enum.valueOf(rawClass, key.toUpperCase());
                        }
                    };
                }
            });

I appreciate the code around here is fairly complex.

Related issues (possibly):
#749
#1313

@cowtowncoder
Copy link
Member

Thank you for reporting this. Couple of questions first:

  • Which jackson version is this (verified) with?
  • Does this also occur with standard JDK collections, or just with Guava ones?

@alfonsobonso
Copy link
Author

Version is 2.8.4. I had also been running with 2.6.4, which had the same issue, and upgraded as part of my digging.
I confirm this is also happening with standard JDK collections.

@cowtowncoder
Copy link
Member

Thank you for verifying this. Being able to test with JDK collections makes it bit easier to repro with just databind.

@alfonsobonso
Copy link
Author

Fast! Thank you very much.

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