HHH-5580 - Improving findEntityTypesChangedInRevision() method performance
This commit is contained in:
parent
94590c5062
commit
7dc925fcf6
|
@ -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 {
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue