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.checkNotNull;
|
||||||
import static org.hibernate.envers.tools.ArgumentsTools.checkPositive;
|
import static org.hibernate.envers.tools.ArgumentsTools.checkPositive;
|
||||||
|
|
||||||
|
import java.lang.reflect.Member;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import javax.persistence.NoResultException;
|
import javax.persistence.NoResultException;
|
||||||
import org.hibernate.Criteria;
|
import org.hibernate.Criteria;
|
||||||
|
@ -56,6 +57,7 @@ public class AuditReaderImpl implements AuditReaderImplementor {
|
||||||
private final SessionImplementor sessionImplementor;
|
private final SessionImplementor sessionImplementor;
|
||||||
private final Session session;
|
private final Session session;
|
||||||
private final FirstLevelCache firstLevelCache;
|
private final FirstLevelCache firstLevelCache;
|
||||||
|
private Member modifiedEntityTypesProperty = null;
|
||||||
|
|
||||||
public AuditReaderImpl(AuditConfiguration verCfg, Session session,
|
public AuditReaderImpl(AuditConfiguration verCfg, Session session,
|
||||||
SessionImplementor sessionImplementor) {
|
SessionImplementor sessionImplementor) {
|
||||||
|
@ -292,8 +294,12 @@ public class AuditReaderImpl implements AuditReaderImplementor {
|
||||||
Object revisionInfo = query.uniqueResult();
|
Object revisionInfo = query.uniqueResult();
|
||||||
if (revisionInfo != null) {
|
if (revisionInfo != null) {
|
||||||
// If revision exists
|
// If revision exists
|
||||||
// Only one field can be marked with @ModifiedEntityTypes annotation
|
if (modifiedEntityTypesProperty == null) {
|
||||||
Set<String> modifiedEntityTypes = (Set<String>) ReflectionTools.getAnnotatedMembersValues(revisionInfo, ModifiedEntityTypes.class).values().toArray()[0];
|
// 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());
|
Set<Class> result = new HashSet<Class>(modifiedEntityTypes.size());
|
||||||
for (String entityClassName : modifiedEntityTypes) {
|
for (String entityClassName : modifiedEntityTypes) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -102,28 +102,47 @@ public class ReflectionTools {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param object Not {@code null} instance.
|
* Returns property value by invoking getter method or directly retrieving field's reference.
|
||||||
* @param annotation Searched annotation.
|
* @param member Field or getter method representation.
|
||||||
* @return Map with the following structure:
|
* @param object Object instance.
|
||||||
* <ul>
|
* @return Property value.
|
||||||
* <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>
|
|
||||||
*/
|
*/
|
||||||
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 {
|
try {
|
||||||
Set<Field> annotatedFields = new HashSet<Field>();
|
Set<Field> annotatedFields = new HashSet<Field>();
|
||||||
Set<Method> annotatedMethods = new HashSet<Method>();
|
Set<Method> annotatedMethods = new HashSet<Method>();
|
||||||
doGetAnnotatedFields(object.getClass(), annotation, annotatedFields);
|
doGetAnnotatedFields(clazz, annotation, annotatedFields);
|
||||||
doGetAnnotatedMethods(object.getClass(), annotation, annotatedMethods);
|
doGetAnnotatedMethods(clazz, annotation, annotatedMethods);
|
||||||
Map<Member, Object> result = new HashMap<Member, Object>(annotatedFields.size() + annotatedMethods.size());
|
Set<Member> result = new HashSet<Member>(annotatedFields.size() + annotatedMethods.size());
|
||||||
for (Field field : annotatedFields) {
|
for (Field field : annotatedFields) {
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
result.put(field, field.get(object));
|
result.add(field);
|
||||||
}
|
}
|
||||||
for (Method method : annotatedMethods) {
|
for (Method method : annotatedMethods) {
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
result.put(method, method.invoke(object));
|
result.add(method);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -133,7 +152,7 @@ public class ReflectionTools {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populates {@code fields} set with all properties marked with a given annotation.
|
* 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 annotation Annotation.
|
||||||
* @param fields Set of annotated fields. Shall be initialized externally.
|
* @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.
|
* 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 annotation Annotation.
|
||||||
* @param methods Set of annotated methods. Shall be initialized externally.
|
* @param methods Set of annotated methods. Shall be initialized externally.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue