16
16
package org .springframework .data .convert ;
17
17
18
18
import java .lang .annotation .Annotation ;
19
- import java .util .ArrayList ;
20
- import java .util .Arrays ;
21
- import java .util .Collection ;
22
- import java .util .Collections ;
23
- import java .util .HashSet ;
24
- import java .util .LinkedHashSet ;
25
- import java .util .List ;
26
- import java .util .Map ;
27
- import java .util .Optional ;
28
- import java .util .Set ;
29
- import java .util .concurrent .ConcurrentHashMap ;
19
+ import java .util .*;
30
20
import java .util .function .Function ;
31
21
import java .util .function .Predicate ;
32
22
import java .util .stream .Collectors ;
33
23
34
24
import org .apache .commons .logging .Log ;
35
25
import org .apache .commons .logging .LogFactory ;
26
+
36
27
import org .springframework .core .GenericTypeResolver ;
37
28
import org .springframework .core .annotation .AnnotationUtils ;
38
29
import org .springframework .core .convert .converter .Converter ;
@@ -119,7 +110,7 @@ public class CustomConversions {
119
110
private final Function <ConvertiblePair , Class <?>> getRawWriteTarget = convertiblePair -> getCustomTarget (
120
111
convertiblePair .getSourceType (), null , writingPairs );
121
112
122
- @ Nullable private final PropertyValueConversions propertyValueConversions ;
113
+ private final @ Nullable PropertyValueConversions propertyValueConversions ;
123
114
124
115
/**
125
116
* @param converterConfiguration the {@link ConverterConfiguration} to apply.
@@ -506,7 +497,7 @@ private Class<?> getCustomTarget(Class<?> sourceType, @Nullable Class<?> targetT
506
497
*/
507
498
static class ConversionTargetsCache {
508
499
509
- private final Map <Class <?>, TargetTypes > customReadTargetTypes = new ConcurrentHashMap <>();
500
+ private Map <Class <?>, TargetTypes > customReadTargetTypes = new HashMap <>();
510
501
511
502
/**
512
503
* Get or compute a target type given its {@code sourceType}. Returns a cached {@link Optional} if the value
@@ -536,7 +527,15 @@ public Class<?> computeIfAbsent(Class<?> sourceType, Function<ConvertiblePair, C
536
527
public Class <?> computeIfAbsent (Class <?> sourceType , Class <?> targetType ,
537
528
Function <ConvertiblePair , Class <?>> mappingFunction ) {
538
529
539
- TargetTypes targetTypes = customReadTargetTypes .computeIfAbsent (sourceType , TargetTypes ::new );
530
+ TargetTypes targetTypes = customReadTargetTypes .get (sourceType );
531
+
532
+ if (targetTypes == null ) {
533
+
534
+ Map <Class <?>, TargetTypes > customReadTargetTypes = new HashMap <>(this .customReadTargetTypes );
535
+ targetTypes = new TargetTypes (sourceType );
536
+ customReadTargetTypes .put (sourceType , targetTypes );
537
+ this .customReadTargetTypes = customReadTargetTypes ;
538
+ }
540
539
541
540
return targetTypes .computeIfAbsent (targetType , mappingFunction );
542
541
}
@@ -555,7 +554,7 @@ interface AbsentTargetTypeMarker {}
555
554
static class TargetTypes {
556
555
557
556
private final Class <?> sourceType ;
558
- private final Map <Class <?>, Class <?>> conversionTargets = new ConcurrentHashMap <>();
557
+ private Map <Class <?>, Class <?>> conversionTargets = new HashMap <>();
559
558
560
559
TargetTypes (Class <?> sourceType ) {
561
560
this .sourceType = sourceType ;
@@ -576,17 +575,21 @@ public Class<?> computeIfAbsent(Class<?> targetType, Function<ConvertiblePair, C
576
575
Class <?> optionalTarget = conversionTargets .get (targetType );
577
576
578
577
if (optionalTarget == null ) {
578
+
579
579
optionalTarget = mappingFunction .apply (new ConvertiblePair (sourceType , targetType ));
580
+
581
+ Map <Class <?>, Class <?>> conversionTargets = new HashMap <>(this .conversionTargets );
580
582
conversionTargets .put (targetType , optionalTarget == null ? Void .class : optionalTarget );
583
+ this .conversionTargets = conversionTargets ;
581
584
}
582
585
583
586
return Void .class .equals (optionalTarget ) ? null : optionalTarget ;
584
587
}
585
588
}
586
589
587
590
/**
588
- * Value class tying together a {@link ConverterRegistration} and its {@link ConverterOrigin origin} to allow fine
589
- * grained registration based on store supported types.
591
+ * Value class tying together a {@link ConverterRegistration} and its {@link ConverterOrigin origin} to allow
592
+ * fine- grained registration based on store supported types.
590
593
*
591
594
* @since 2.3
592
595
* @author Christoph Strobl
0 commit comments