@@ -204,7 +204,7 @@ protected JsonDeserializer<Object> _findCachedDeserializer(JavaType type)
204204 if (type == null ) {
205205 throw new IllegalArgumentException ("Null JavaType passed" );
206206 }
207- if (_hasCustomValueHandler (type )) {
207+ if (_hasCustomHandlers (type )) {
208208 return null ;
209209 }
210210 return _cachedDeserializers .get (type );
@@ -274,7 +274,7 @@ protected JsonDeserializer<Object> _createAndCache2(DeserializationContext ctxt,
274274 * (but can be re-defined for sub-classes by using @JsonCachable!)
275275 */
276276 // 27-Mar-2015, tatu: As per [databind#735], avoid caching types with custom value desers
277- boolean addToCache = !_hasCustomValueHandler (type ) && deser .isCachable ();
277+ boolean addToCache = !_hasCustomHandlers (type ) && deser .isCachable ();
278278
279279 /* we will temporarily hold on to all created deserializers (to
280280 * handle cyclic references, and possibly reuse non-cached
@@ -531,13 +531,23 @@ private JavaType modifyTypeByAnnotation(DeserializationContext ctxt,
531531 * Helper method used to prevent both caching and cache lookups for structured
532532 * types that have custom value handlers
533533 *
534- * @since 2.4.6
534+ * @since 2.8.11
535535 */
536- private boolean _hasCustomValueHandler (JavaType t ) {
536+ private boolean _hasCustomHandlers (JavaType t ) {
537537 if (t .isContainerType ()) {
538+ // First: value types may have both value and type handlers
538539 JavaType ct = t .getContentType ();
539540 if (ct != null ) {
540- return (ct .getValueHandler () != null ) || (ct .getTypeHandler () != null );
541+ if ((ct .getValueHandler () != null ) || (ct .getTypeHandler () != null )) {
542+ return true ;
543+ }
544+ }
545+ // Second: map(-like) types may have value handler for key (but not type; keys are untyped)
546+ if (t .isMapLikeType ()) {
547+ JavaType kt = t .getKeyType ();
548+ if (kt .getValueHandler () != null ) {
549+ return true ;
550+ }
541551 }
542552 }
543553 return false ;
@@ -568,9 +578,7 @@ private Class<?> _verifyAsClass(Object src, String methodName, Class<?> noneClas
568578 protected JsonDeserializer <Object > _handleUnknownValueDeserializer (DeserializationContext ctxt , JavaType type )
569579 throws JsonMappingException
570580 {
571- /* Let's try to figure out the reason, to give better error
572- * messages
573- */
581+ // Let's try to figure out the reason, to give better error messages
574582 Class <?> rawClass = type .getRawClass ();
575583 if (!ClassUtil .isConcrete (rawClass )) {
576584 ctxt .reportMappingException ("Can not find a Value deserializer for abstract type %s" , type );
0 commit comments