DATACMNS-1271 - Streamlined implementation of AnnotationBasedPersistentProperty to avoid NullPointerExceptions.
We now use the annotation cache's ….computeIfAbsent(…) to avoid inconsistencies between ….contains(…) and ….get(…) in multi-threaded scenarios.
This commit is contained in:
@@ -39,6 +39,7 @@ import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.util.Lazy;
|
||||
import org.springframework.data.util.Optionals;
|
||||
import org.springframework.data.util.StreamUtils;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -229,22 +230,13 @@ public abstract class AnnotationBasedPersistentProperty<P extends PersistentProp
|
||||
@SuppressWarnings("unchecked")
|
||||
private <A extends Annotation> Optional<A> doFindAnnotation(Class<A> annotationType) {
|
||||
|
||||
if (annotationCache != null && annotationCache.containsKey(annotationType)) {
|
||||
return (Optional<A>) annotationCache.get(annotationType);
|
||||
}
|
||||
return (Optional<A>) annotationCache.computeIfAbsent(annotationType, type -> {
|
||||
|
||||
return cacheAndReturn(annotationType, getAccessors()//
|
||||
.flatMap(it -> {
|
||||
|
||||
A mergedAnnotation = AnnotatedElementUtils.findMergedAnnotation(it, annotationType);
|
||||
|
||||
if (mergedAnnotation == null) {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
return Stream.of(mergedAnnotation);
|
||||
})//
|
||||
.findFirst());
|
||||
return getAccessors() //
|
||||
.map(it -> AnnotatedElementUtils.findMergedAnnotation(it, type)) //
|
||||
.flatMap(StreamUtils::fromNullable) //
|
||||
.findFirst();
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -260,18 +252,6 @@ public abstract class AnnotationBasedPersistentProperty<P extends PersistentProp
|
||||
return annotation != null ? annotation : getOwner().findAnnotation(annotationType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the given annotation into the local cache and returns it.
|
||||
*
|
||||
* @param annotation
|
||||
* @return
|
||||
*/
|
||||
private <A extends Annotation> Optional<A> cacheAndReturn(Class<? extends A> type, Optional<A> annotation) {
|
||||
|
||||
annotationCache.put(type, annotation);
|
||||
return annotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the property carries the an annotation of the given type.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user