@@ -347,12 +347,7 @@ private boolean handleArray(JsonNode node, Object source, ObjectMapper mapper, T
347
347
return false ;
348
348
}
349
349
350
- Iterator <Object > iterator = collection .iterator ();
351
- TypeInformation <?> componentType = iterator .hasNext () ? //
352
- ClassTypeInformation .from (iterator .next ().getClass ()) : //
353
- collectionType .getComponentType ();
354
-
355
- return handleArrayNode ((ArrayNode ) node , collection , mapper , componentType );
350
+ return handleArrayNode ((ArrayNode ) node , collection , mapper , collectionType .getComponentType ());
356
351
}
357
352
358
353
/**
@@ -380,16 +375,15 @@ private boolean handleArrayNode(ArrayNode array, Collection<Object> collection,
380
375
381
376
if (!value .hasNext ()) {
382
377
383
- Class <?> type = componentType == null ? Object .class : componentType .getType ();
384
- collection .add (mapper .treeToValue (jsonNode , type ));
378
+ collection .add (mapper .treeToValue (jsonNode , getTypeToMap (null , componentType ).getType ()));
385
379
386
380
continue ;
387
381
}
388
382
389
383
Object next = value .next ();
390
384
391
385
if (ArrayNode .class .isInstance (jsonNode )) {
392
- return handleArray (jsonNode , next , mapper , componentType );
386
+ return handleArray (jsonNode , next , mapper , getTypeToMap ( value , componentType ) );
393
387
}
394
388
395
389
if (ObjectNode .class .isInstance (jsonNode )) {
@@ -424,7 +418,7 @@ private void doMergeNestedMap(Map<Object, Object> source, ObjectNode node, Objec
424
418
425
419
Iterator <Entry <String , JsonNode >> fields = node .fields ();
426
420
Class <?> keyType = typeOrObject (type .getComponentType ());
427
- Class <?> valueType = typeOrObject ( type .getMapValueType () );
421
+ TypeInformation <?> valueType = type .getMapValueType ();
428
422
429
423
while (fields .hasNext ()) {
430
424
@@ -434,19 +428,19 @@ private void doMergeNestedMap(Map<Object, Object> source, ObjectNode node, Objec
434
428
435
429
Object mappedKey = mapper .readValue (quote (key ), keyType );
436
430
Object sourceValue = source .get (mappedKey );
431
+ TypeInformation <?> typeToMap = getTypeToMap (sourceValue , valueType );
437
432
438
433
if (value instanceof ObjectNode && sourceValue != null ) {
439
434
440
435
doMerge ((ObjectNode ) value , sourceValue , mapper );
441
436
442
437
} else if (value instanceof ArrayNode && sourceValue != null ) {
443
438
444
- handleArray (value , sourceValue , mapper , type );
439
+ handleArray (value , sourceValue , mapper , getTypeToMap ( sourceValue , typeToMap ) );
445
440
446
441
} else {
447
442
448
- Class <?> typeToRead = sourceValue != null ? sourceValue .getClass () : valueType ;
449
- source .put (mappedKey , mapper .treeToValue (value , typeToRead ));
443
+ source .put (mappedKey , mapper .treeToValue (value , typeToMap .getType ()));
450
444
}
451
445
452
446
fields .remove ();
@@ -562,6 +556,32 @@ private static Class<?> typeOrObject(TypeInformation<?> type) {
562
556
return type == null ? Object .class : type .getType ();
563
557
}
564
558
559
+ /**
560
+ * Returns the type to read for the given value and default type. The type will be defaulted to {@link Object} if
561
+ * missing. If the given value's type is different from the given default (i.e. more concrete) the value's type will
562
+ * be used.
563
+ *
564
+ * @param value can be {@literal null}.
565
+ * @param type can be {@literal null}.
566
+ * @return
567
+ */
568
+ private static TypeInformation <?> getTypeToMap (Object value , TypeInformation <?> type ) {
569
+
570
+ if (type == null ) {
571
+ type = ClassTypeInformation .OBJECT ;
572
+ }
573
+
574
+ if (value == null ) {
575
+ return type ;
576
+ }
577
+
578
+ if (Enum .class .isInstance (value )) {
579
+ return ClassTypeInformation .from (((Enum <?>) value ).getDeclaringClass ());
580
+ }
581
+
582
+ return value .getClass ().equals (type .getType ()) ? type : ClassTypeInformation .from (value .getClass ());
583
+ }
584
+
565
585
/**
566
586
* Simple value object to capture a mapping of Jackson mapped field names and {@link PersistentProperty} instances.
567
587
*
0 commit comments