HHH-5580 - Improving findEntityTypesChangedInRevision() method performance

This commit is contained in:
Lukasz Antoniak 2011-05-16 22:06:45 +02:00
parent 94590c5062
commit 7dc925fcf6
2 changed files with 43 additions and 18 deletions

View File

@ -25,6 +25,7 @@ package org.hibernate.envers.reader;
import static org.hibernate.envers.tools.ArgumentsTools.checkNotNull;
import static org.hibernate.envers.tools.ArgumentsTools.checkPositive;
import java.lang.reflect.Member;
import java.util.*;
import javax.persistence.NoResultException;
import org.hibernate.Criteria;
@ -56,6 +57,7 @@ public class AuditReaderImpl implements AuditReaderImplementor {
private final SessionImplementor sessionImplementor;
private final Session session;
private final FirstLevelCache firstLevelCache;
private Member modifiedEntityTypesProperty = null;
public AuditReaderImpl(AuditConfiguration verCfg, Session session,
SessionImplementor sessionImplementor) {
@ -292,8 +294,12 @@ public class AuditReaderImpl implements AuditReaderImplementor {
Object revisionInfo = query.uniqueResult();
if (revisionInfo != null) {
// If revision exists
// Only one field can be marked with @ModifiedEntityTypes annotation
Set<String> modifiedEntityTypes = (Set<String>) ReflectionTools.getAnnotatedMembersValues(revisionInfo, ModifiedEntityTypes.class).values().toArray()[0];
if (modifiedEntityTypesProperty == null) {
// Only one field or method (getter) can be marked with @ModifiedEntityTypes annotation
modifiedEntityTypesProperty = (Member) ReflectionTools.getAnnotatedMembers(revisionInfo.getClass(),
ModifiedEntityTypes.class).toArray()[0];
}
Set<String> modifiedEntityTypes = (Set<String>) ReflectionTools.getPropertyValue(modifiedEntityTypesProperty, revisionInfo);
Set<Class> result = new HashSet<Class>(modifiedEntityTypes.size());
for (String entityClassName : modifiedEntityTypes) {
try {

View File

@ -101,29 +101,48 @@ public class ReflectionTools {
return value;
}
/**
* @param object Not {@code null} instance.
* @param annotation Searched annotation.
* @return Map with the following structure:
* <ul>
* <li>key - members ({@link Field} and/or {@link Method}) that have been marked with a given annotation.</li>
* <li>value - object returned by the method invocation or field's value.</li>
* </ul>
/**
* Returns property value by invoking getter method or directly retrieving field's reference.
* @param member Field or getter method representation.
* @param object Object instance.
* @return Property value.
*/
public static Map<Member, Object> getAnnotatedMembersValues(Object object, Class<? extends Annotation> annotation) {
public static Object getPropertyValue(Member member, Object object) {
try {
if (member instanceof Field) {
Field field = (Field) member;
field.setAccessible(true);
return field.get(object);
} else if (member instanceof Method) {
Method method = (Method) member;
method.setAccessible(true);
return method.invoke(object);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
throw new IllegalArgumentException("Unsupported member type: " + member + ".");
}
/**
* @param clazz Class type.
* @param annotation Searched annotation.
* @return Set of annotated members ({@link Field} and/or {@link Method}).
*/
public static Set<Member> getAnnotatedMembers(Class clazz, Class<? extends Annotation> annotation) {
try {
Set<Field> annotatedFields = new HashSet<Field>();
Set<Method> annotatedMethods = new HashSet<Method>();
doGetAnnotatedFields(object.getClass(), annotation, annotatedFields);
doGetAnnotatedMethods(object.getClass(), annotation, annotatedMethods);
Map<Member, Object> result = new HashMap<Member, Object>(annotatedFields.size() + annotatedMethods.size());
doGetAnnotatedFields(clazz, annotation, annotatedFields);
doGetAnnotatedMethods(clazz, annotation, annotatedMethods);
Set<Member> result = new HashSet<Member>(annotatedFields.size() + annotatedMethods.size());
for (Field field : annotatedFields) {
field.setAccessible(true);
result.put(field, field.get(object));
result.add(field);
}
for (Method method : annotatedMethods) {
method.setAccessible(true);
result.put(method, method.invoke(object));
result.add(method);
}
return result;
} catch (Exception e) {
@ -133,7 +152,7 @@ public class ReflectionTools {
/**
* Populates {@code fields} set with all properties marked with a given annotation.
* @param clazz Object's class type.
* @param clazz Class type.
* @param annotation Annotation.
* @param fields Set of annotated fields. Shall be initialized externally.
*/
@ -152,7 +171,7 @@ public class ReflectionTools {
/**
* Populates {@code methods} set with all functions marked with a given annotation.
* @param clazz Object's class type.
* @param clazz Class type.
* @param annotation Annotation.
* @param methods Set of annotated methods. Shall be initialized externally.
*/