3434import org .springframework .data .mapping .MappingException ;
3535import org .springframework .data .util .DirectFieldAccessFallbackBeanWrapper ;
3636import org .springframework .util .Assert ;
37+ import org .springframework .util .ClassUtils ;
3738import org .springframework .util .NumberUtils ;
39+ import org .springframework .util .ObjectUtils ;
3840import org .springframework .util .StringUtils ;
3941
4042import com .fasterxml .jackson .annotation .JsonInclude .Include ;
153155 */
154156public class Jackson2HashMapper implements HashMapper <Object , String , Object >, HashObjectReader <String , Object > {
155157
158+ private static final boolean SOURCE_VERSION_PRESENT = ClassUtils .isPresent ("javax.lang.model.SourceVersion" , Jackson2HashMapper .class .getClassLoader ());
159+
156160 private final HashMapperModule HASH_MAPPER_MODULE = new HashMapperModule ();
157161
158162 private final ObjectMapper typingMapper ;
@@ -287,8 +291,7 @@ public <R> R fromHash(Class<R> type, Map<String, Object> hash) {
287291
288292 if (flatten ) {
289293
290- return typingMapper .reader ().forType (type )
291- .readValue (untypedMapper .writeValueAsBytes (doUnflatten (hash )));
294+ return typingMapper .reader ().forType (type ).readValue (untypedMapper .writeValueAsBytes (doUnflatten (hash )));
292295 }
293296
294297 return typingMapper .treeToValue (untypedMapper .valueToTree (hash ), type );
@@ -394,10 +397,42 @@ private void flattenElement(String propertyPrefix, Object source, Map<String, Ob
394397 if (cur .isArray ()) {
395398 this .flattenCollection (propertyPrefix , cur .elements (), resultMap );
396399 } else {
400+ if (nodes .hasNext () && mightBeJavaType (cur )) {
401+
402+ JsonNode next = nodes .next ();
403+
404+ if (next .isArray ()) {
405+ this .flattenCollection (propertyPrefix , next .elements (), resultMap );
406+ }
407+
408+ if (cur .asText ().equals ("java.util.Date" )) {
409+ resultMap .put (propertyPrefix , next .asText ());
410+ break ;
411+ }
412+ if (next .isNumber ()) {
413+ resultMap .put (propertyPrefix , next .numberValue ());
414+ break ;
415+ }
416+ if (next .isTextual ()) {
417+
418+ resultMap .put (propertyPrefix , next .textValue ());
419+ break ;
420+ }
421+ if (next .isBoolean ()) {
422+
423+ resultMap .put (propertyPrefix , next .booleanValue ());
424+ break ;
425+ }
426+ if (next .isBinary ()) {
427+
428+ try {
429+ resultMap .put (propertyPrefix , next .binaryValue ());
430+ } catch (IOException e ) {
431+ throw new IllegalStateException (String .format ("Cannot read binary value of '%s'" , propertyPrefix ), e );
432+ }
433+ break ;
434+ }
397435
398- if (cur .asText ().equals ("java.util.Date" )) {
399- resultMap .put (propertyPrefix , nodes .next ().asText ());
400- break ;
401436 }
402437 }
403438 }
@@ -409,6 +444,27 @@ private void flattenElement(String propertyPrefix, Object source, Map<String, Ob
409444 }
410445 }
411446
447+ private boolean mightBeJavaType (JsonNode node ) {
448+
449+ String textValue = node .asText ();
450+ if (!SOURCE_VERSION_PRESENT ) {
451+
452+ if (ObjectUtils .nullSafeEquals (textValue , "java.util.Date" )) {
453+ return true ;
454+ }
455+ if (ObjectUtils .nullSafeEquals (textValue , "java.math.BigInteger" )) {
456+ return true ;
457+ }
458+ if (ObjectUtils .nullSafeEquals (textValue , "java.math.BigDecimal" )) {
459+ return true ;
460+ }
461+
462+ return false ;
463+ }
464+ return javax .lang .model .SourceVersion .isName (textValue );
465+
466+ }
467+
412468 private void flattenCollection (String propertyPrefix , Iterator <JsonNode > list , Map <String , Object > resultMap ) {
413469
414470 int counter = 0 ;
0 commit comments