DATACMNS-282 - Improved caching in AnnotationBasedPersistentProperty.

AnnotationBasedPersistentProperty now caches direct annotations on construction but still tries to lookup an annotation as meta-annotation if not found in cache on later requests. Extended try/catch block in AbstractMappingContext.addPersistentEntity(…) to invalidate cache on exceptions during property creation as well.
This commit is contained in:
Oliver Gierke
2013-02-11 15:56:14 +01:00
parent 0bbe56740b
commit 0bbf0aec99
3 changed files with 117 additions and 4 deletions

View File

@@ -278,11 +278,12 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
descriptors.put(descriptor.getName(), descriptor);
}
ReflectionUtils.doWithFields(type, new PersistentPropertyCreator(entity, descriptors),
PersistentFieldFilter.INSTANCE);
try {
ReflectionUtils.doWithFields(type, new PersistentPropertyCreator(entity, descriptors),
PersistentFieldFilter.INSTANCE);
entity.verify();
} catch (MappingException e) {
persistentEntities.remove(typeInformation);
throw e;

View File

@@ -59,9 +59,49 @@ public abstract class AnnotationBasedPersistentProperty<P extends PersistentProp
PersistentEntity<?, P> owner, SimpleTypeHolder simpleTypeHolder) {
super(field, propertyDescriptor, owner, simpleTypeHolder);
populateAnnotationCache(field);
this.value = findAnnotation(Value.class);
}
/**
* Populates the annotation cache by eagerly accessing the annotations directly annotated to the accessors (if
* available) and the backing field. Annotations override annotations found on field.
*
* @param field
* @throws MappingException in case we find an ambiguous mapping on the accessor methods
*/
private final void populateAnnotationCache(Field field) {
for (Method method : Arrays.asList(getGetter(), getSetter())) {
if (method == null) {
continue;
}
for (Annotation annotation : method.getAnnotations()) {
Class<? extends Annotation> annotationType = annotation.annotationType();
if (annotationCache.containsKey(annotationType)) {
throw new MappingException(String.format("Ambiguous mapping! Annotation %s configured "
+ "multiple times on accessor methods of property %s in class %s!", annotationType, getName(), getOwner()
.getType().getName()));
}
annotationCache.put(annotationType, annotation);
}
}
for (Annotation annotation : field.getAnnotations()) {
Class<? extends Annotation> annotationType = annotation.annotationType();
if (!annotationCache.containsKey(annotationType)) {
annotationCache.put(annotationType, annotation);
}
}
}
/**
* Inspects a potentially available {@link Value} annotation at the property and returns the {@link String} value of
* it.