diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/StdKeyDeserializers.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/StdKeyDeserializers.java index c2ddab4be4..4a66a8f370 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/std/StdKeyDeserializers.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/StdKeyDeserializers.java @@ -52,15 +52,7 @@ public static KeyDeserializer findStringBasedKeyDeserializer(DeserializationCont // We don't need full deserialization information, just need to know creators. BeanDescription beanDesc = ctxt.introspect(type); - // Ok, so: can we find T(String) constructor? - Constructor ctor = beanDesc.findSingleArgConstructor(String.class); - if (ctor != null) { - if (ctxt.canOverrideAccessModifiers()) { - ClassUtil.checkAndFixAccess(ctor, ctxt.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS)); - } - return new StdKeyDeserializer.StringCtorKeyDeserializer(ctor); - } - /* or if not, "static T valueOf(String)" (or equivalent marked + /* Ok, so: can we find "static T valueOf(String)" (or equivalent marked * with @JsonCreator annotation?) */ Method m = beanDesc.findFactoryMethod(String.class); @@ -70,6 +62,16 @@ public static KeyDeserializer findStringBasedKeyDeserializer(DeserializationCont } return new StdKeyDeserializer.StringFactoryKeyDeserializer(m); } + + // or if not, a T(String) constructor? + Constructor ctor = beanDesc.findSingleArgConstructor(String.class); + if (ctor != null) { + if (ctxt.canOverrideAccessModifiers()) { + ClassUtil.checkAndFixAccess(ctor, ctxt.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS)); + } + return new StdKeyDeserializer.StringCtorKeyDeserializer(ctor); + } + // nope, no such luck... return null; } diff --git a/src/test/java/com/fasterxml/jackson/databind/deser/TestGenericMapDeser.java b/src/test/java/com/fasterxml/jackson/databind/deser/TestGenericMapDeser.java index e18dd25757..36c5f76da5 100644 --- a/src/test/java/com/fasterxml/jackson/databind/deser/TestGenericMapDeser.java +++ b/src/test/java/com/fasterxml/jackson/databind/deser/TestGenericMapDeser.java @@ -71,7 +71,28 @@ public static KeyTypeFactory create(String str) { return new KeyTypeFactory(str, true); } } - + + static class KeyTypeFactoryPrecedence { + protected String value; + public KeyTypeFactoryPrecedence(String v) { + this(v, false); + } + + private KeyTypeFactoryPrecedence(String v, boolean factory) { + if (factory) { + value = "factory:" + v; + } + else { + value = "ctor:" + v; + } + } + + @JsonCreator + public static KeyTypeFactoryPrecedence create(String str) { + return new KeyTypeFactoryPrecedence(str, true); + } + } + /* /********************************************************** /* Test methods for sub-classing @@ -167,4 +188,18 @@ public void testKeyViaFactory() throws Exception assertEquals("a", ((KeyTypeFactory) key).value); } + + public void testKeyViaFactoryPrecedenceOverConstructor() throws Exception + { + ObjectMapper mapper = new ObjectMapper(); + Map map = mapper.readValue("{\"a\":123}", + TypeFactory.defaultInstance().constructMapType(HashMap.class, KeyTypeFactoryPrecedence.class, Integer.class)); + assertEquals(1, map.size()); + Map.Entry entry = map.entrySet().iterator().next(); + assertEquals(Integer.valueOf(123), entry.getValue()); + Object key = entry.getKey(); + assertEquals(KeyTypeFactoryPrecedence.class, key.getClass()); + assertEquals("factory:a", ((KeyTypeFactoryPrecedence) key).value); + } + }