18
18
import java .lang .reflect .Field ;
19
19
import java .lang .reflect .Method ;
20
20
import java .lang .reflect .Modifier ;
21
- import java .util .Collection ;
22
21
import java .util .Collections ;
23
- import java .util .LinkedHashSet ;
22
+ import java .util .HashSet ;
24
23
import java .util .Map ;
25
24
import java .util .Optional ;
26
25
import java .util .Set ;
27
- import java .util .function . Supplier ;
26
+ import java .util .stream . Collectors ;
28
27
29
28
import org .springframework .data .mapping .Association ;
30
29
import org .springframework .data .mapping .PersistentEntity ;
31
30
import org .springframework .data .mapping .PersistentProperty ;
32
31
import org .springframework .data .util .Lazy ;
33
- import org .springframework .data .util .NullableWrapperConverters ;
34
32
import org .springframework .data .util .ReflectionUtils ;
35
33
import org .springframework .data .util .TypeInformation ;
36
34
import org .springframework .lang .Nullable ;
@@ -64,11 +62,10 @@ public abstract class AbstractPersistentProperty<P extends PersistentProperty<P>
64
62
private final Property property ;
65
63
private final Lazy <Integer > hashCode ;
66
64
private final Lazy <Boolean > usePropertyAccess ;
67
- private final Lazy <TypeInformation <?>> entityTypeInformation ;
65
+ private final Lazy <Set < TypeInformation <?> >> entityTypeInformation ;
68
66
69
67
private final Lazy <Boolean > isAssociation ;
70
68
private final Lazy <TypeInformation <?>> associationTargetType ;
71
- private final Lazy <Collection <TypeInformation <?>>> entityTypes ;
72
69
73
70
private final Method getter ;
74
71
private final Method setter ;
@@ -100,10 +97,7 @@ public AbstractPersistentProperty(Property property, PersistentEntity<?, P> owne
100
97
.map (TypeInformation ::getComponentType ) //
101
98
.orElse (null ));
102
99
103
- this .entityTypeInformation = Lazy .of (() -> Optional .ofNullable (getAssociationOrActualType ())
104
- .filter (it -> !simpleTypeHolder .isSimpleType (it .getType ())) //
105
- .filter (it -> !it .isCollectionLike ()) //
106
- .filter (it -> !it .isMap ()).orElse (null ));
100
+ this .entityTypeInformation = Lazy .of (() -> detectEntityTypes (simpleTypeHolder ));
107
101
108
102
this .getter = property .getGetter ().orElse (null );
109
103
this .setter = property .getSetter ().orElse (null );
@@ -115,45 +109,6 @@ public AbstractPersistentProperty(Property property, PersistentEntity<?, P> owne
115
109
} else {
116
110
this .immutable = false ;
117
111
}
118
-
119
- this .entityTypes = Lazy .of (() -> collectEntityTypes (simpleTypeHolder , information , new LinkedHashSet <>()));
120
- }
121
-
122
- protected Set <TypeInformation <?>> collectEntityTypes (SimpleTypeHolder simpleTypeHolder ,
123
- @ Nullable TypeInformation <?> typeInformation , Set <TypeInformation <?>> entityTypes ) {
124
-
125
- if (typeInformation == null || entityTypes .contains (typeInformation )
126
- || simpleTypeHolder .isSimpleType (typeInformation .getType ())) {
127
- return entityTypes ;
128
- }
129
-
130
- if (typeInformation .isMap ()) {
131
-
132
- collectEntityTypes (simpleTypeHolder , typeInformation .getComponentType (), entityTypes );
133
- collectEntityTypes (simpleTypeHolder , typeInformation .getMapValueType (), entityTypes );
134
- return entityTypes ;
135
- }
136
-
137
- if (typeInformation .isCollectionLike ()) {
138
-
139
- collectEntityTypes (simpleTypeHolder , typeInformation .getComponentType (), entityTypes );
140
- return entityTypes ;
141
- }
142
-
143
- if (NullableWrapperConverters .supports (typeInformation .getType ())) {
144
-
145
- collectEntityTypes (simpleTypeHolder , typeInformation .getActualType (), entityTypes );
146
- return entityTypes ;
147
- }
148
-
149
- if (ASSOCIATION_TYPE != null && ASSOCIATION_TYPE .isAssignableFrom (typeInformation .getType ())) {
150
-
151
- entityTypes .add (getAssociationOrActualType ());
152
- return entityTypes ;
153
- }
154
-
155
- entityTypes .add (typeInformation );
156
- return entityTypes ;
157
112
}
158
113
159
114
protected abstract Association <P > createAssociation ();
@@ -211,14 +166,14 @@ public TypeInformation<?> getTypeInformation() {
211
166
public Iterable <? extends TypeInformation <?>> getPersistentEntityTypes () {
212
167
213
168
if (isMap () || isCollectionLike ()) {
214
- return entityTypes .get ();
169
+ return entityTypeInformation .get ();
215
170
}
216
171
217
172
if (!isEntity ()) {
218
173
return Collections .emptySet ();
219
174
}
220
175
221
- return entityTypes .get ();
176
+ return entityTypeInformation .get ();
222
177
}
223
178
224
179
/*
@@ -362,7 +317,7 @@ public boolean isArray() {
362
317
*/
363
318
@ Override
364
319
public boolean isEntity () {
365
- return !isTransient () && entityTypeInformation .getNullable () != null ;
320
+ return !isTransient () && ! entityTypeInformation .get (). isEmpty () ;
366
321
}
367
322
368
323
/*
@@ -401,7 +356,11 @@ public Class<?> getMapValueType() {
401
356
*/
402
357
@ Override
403
358
public Class <?> getActualType () {
404
- return getRequiredAssociationOrActualType ().getType ();
359
+
360
+ TypeInformation <?> targetType = associationTargetType .getNullable ();
361
+ TypeInformation <?> result = targetType == null ? information .getRequiredActualType () : targetType ;
362
+
363
+ return result .getType ();
405
364
}
406
365
407
366
/*
@@ -454,23 +413,40 @@ public String toString() {
454
413
return property .toString ();
455
414
}
456
415
457
- @ Nullable
458
- private TypeInformation <?> getAssociationOrActualType () {
459
- return getAssociationTypeOr (() -> information .getActualType ());
460
- }
416
+ private Set <TypeInformation <?>> detectEntityTypes (SimpleTypeHolder simpleTypes ) {
417
+
418
+ TypeInformation <?> typeToStartWith = ASSOCIATION_TYPE != null && ASSOCIATION_TYPE .isAssignableFrom (rawType )
419
+ ? information .getComponentType ()
420
+ : information ;
421
+
422
+ Set <TypeInformation <?>> result = detectEntityTypes (typeToStartWith );
461
423
462
- private TypeInformation <?> getRequiredAssociationOrActualType () {
463
- return getAssociationTypeOr (() -> information .getRequiredActualType ());
424
+ return result .stream ()
425
+ .filter (it -> !simpleTypes .isSimpleType (it .getType ()))
426
+ .filter (it -> !it .getType ().equals (ASSOCIATION_TYPE ))
427
+ .collect (Collectors .toSet ());
464
428
}
465
429
466
- private TypeInformation <?> getAssociationTypeOr ( Supplier < TypeInformation <?>> fallback ) {
430
+ private Set < TypeInformation <?>> detectEntityTypes ( @ Nullable TypeInformation <?> source ) {
467
431
468
- TypeInformation <?> result = associationTargetType .getNullable ();
432
+ if (source == null ) {
433
+ return Collections .emptySet ();
434
+ }
435
+
436
+ Set <TypeInformation <?>> result = new HashSet <>();
469
437
470
- if (result != null ) {
471
- return result ;
438
+ if (source .isMap ()) {
439
+ result .addAll (detectEntityTypes (source .getComponentType ()));
440
+ }
441
+
442
+ TypeInformation <?> actualType = source .getActualType ();
443
+
444
+ if (source .equals (actualType )) {
445
+ result .add (source );
446
+ } else {
447
+ result .addAll (detectEntityTypes (actualType ));
472
448
}
473
449
474
- return fallback . get () ;
450
+ return result ;
475
451
}
476
452
}
0 commit comments