HHH-5580 - Query refactoring
This commit is contained in:
parent
7dc925fcf6
commit
403b15cae8
|
@ -30,6 +30,7 @@ import org.hibernate.annotations.common.reflection.ReflectionManager;
|
|||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.envers.entities.EntitiesConfigurations;
|
||||
import org.hibernate.envers.entities.PropertyData;
|
||||
import org.hibernate.envers.revisioninfo.ModifiedEntityTypesReader;
|
||||
import org.hibernate.envers.revisioninfo.RevisionInfoNumberReader;
|
||||
import org.hibernate.envers.revisioninfo.RevisionInfoQueryCreator;
|
||||
import org.hibernate.envers.strategy.AuditStrategy;
|
||||
|
@ -50,6 +51,7 @@ public class AuditConfiguration {
|
|||
private final EntitiesConfigurations entCfg;
|
||||
private final RevisionInfoQueryCreator revisionInfoQueryCreator;
|
||||
private final RevisionInfoNumberReader revisionInfoNumberReader;
|
||||
private final ModifiedEntityTypesReader modifiedEntityTypesReader;
|
||||
|
||||
public AuditEntitiesConfiguration getAuditEntCfg() {
|
||||
return auditEntCfg;
|
||||
|
@ -75,6 +77,10 @@ public class AuditConfiguration {
|
|||
return revisionInfoNumberReader;
|
||||
}
|
||||
|
||||
public ModifiedEntityTypesReader getModifiedEntityTypesReader() {
|
||||
return modifiedEntityTypesReader;
|
||||
}
|
||||
|
||||
public AuditStrategy getAuditStrategy() {
|
||||
return auditStrategy;
|
||||
}
|
||||
|
@ -90,6 +96,7 @@ public class AuditConfiguration {
|
|||
auditProcessManager = new AuditProcessManager(revInfoCfgResult.getRevisionInfoGenerator());
|
||||
revisionInfoQueryCreator = revInfoCfgResult.getRevisionInfoQueryCreator();
|
||||
revisionInfoNumberReader = revInfoCfgResult.getRevisionInfoNumberReader();
|
||||
modifiedEntityTypesReader = revInfoCfgResult.getModifiedEntityTypesReader();
|
||||
auditStrategy = initializeAuditStrategy(revInfoCfgResult.getRevisionInfoClass(),
|
||||
revInfoCfgResult.getRevisionInfoTimestampData());
|
||||
entCfg = new EntitiesConfigurator().configure(cfg, reflectionManager, globalCfg, auditEntCfg, auditStrategy,
|
||||
|
|
|
@ -309,8 +309,10 @@ public class RevisionInfoConfiguration {
|
|||
new RevisionInfoQueryCreator(revisionInfoEntityName, revisionInfoIdData.getName(),
|
||||
revisionInfoTimestampData.getName(), isTimestampAsDate()),
|
||||
generateRevisionInfoRelationMapping(),
|
||||
new RevisionInfoNumberReader(revisionInfoClass, revisionInfoIdData), revisionInfoEntityName,
|
||||
revisionInfoClass, revisionInfoTimestampData);
|
||||
new RevisionInfoNumberReader(revisionInfoClass, revisionInfoIdData),
|
||||
globalCfg.isTrackEntitiesChangedInRevisionEnabled() ? new ModifiedEntityTypesReader(revisionInfoClass, modifiedEntityTypesData)
|
||||
: null,
|
||||
revisionInfoEntityName, revisionInfoClass, revisionInfoTimestampData);
|
||||
}
|
||||
|
||||
private boolean isTimestampAsDate() {
|
||||
|
@ -325,20 +327,22 @@ class RevisionInfoConfigurationResult {
|
|||
private final RevisionInfoQueryCreator revisionInfoQueryCreator;
|
||||
private final Element revisionInfoRelationMapping;
|
||||
private final RevisionInfoNumberReader revisionInfoNumberReader;
|
||||
private final ModifiedEntityTypesReader modifiedEntityTypesReader;
|
||||
private final String revisionInfoEntityName;
|
||||
private final Class<?> revisionInfoClass;
|
||||
private final PropertyData revisionInfoTimestampData;
|
||||
|
||||
RevisionInfoConfigurationResult(RevisionInfoGenerator revisionInfoGenerator,
|
||||
Document revisionInfoXmlMapping, RevisionInfoQueryCreator revisionInfoQueryCreator,
|
||||
Element revisionInfoRelationMapping,
|
||||
RevisionInfoNumberReader revisionInfoNumberReader, String revisionInfoEntityName, Class<?> revisionInfoClass,
|
||||
PropertyData revisionInfoTimestampData) {
|
||||
Element revisionInfoRelationMapping, RevisionInfoNumberReader revisionInfoNumberReader,
|
||||
ModifiedEntityTypesReader modifiedEntityTypesReader, String revisionInfoEntityName,
|
||||
Class<?> revisionInfoClass, PropertyData revisionInfoTimestampData) {
|
||||
this.revisionInfoGenerator = revisionInfoGenerator;
|
||||
this.revisionInfoXmlMapping = revisionInfoXmlMapping;
|
||||
this.revisionInfoQueryCreator = revisionInfoQueryCreator;
|
||||
this.revisionInfoRelationMapping = revisionInfoRelationMapping;
|
||||
this.revisionInfoNumberReader = revisionInfoNumberReader;
|
||||
this.modifiedEntityTypesReader = modifiedEntityTypesReader;
|
||||
this.revisionInfoEntityName = revisionInfoEntityName;
|
||||
this.revisionInfoClass = revisionInfoClass;
|
||||
this.revisionInfoTimestampData = revisionInfoTimestampData;
|
||||
|
@ -375,4 +379,8 @@ class RevisionInfoConfigurationResult {
|
|||
public PropertyData getRevisionInfoTimestampData() {
|
||||
return revisionInfoTimestampData;
|
||||
}
|
||||
|
||||
public ModifiedEntityTypesReader getModifiedEntityTypesReader() {
|
||||
return modifiedEntityTypesReader;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@ import org.hibernate.HibernateException;
|
|||
import org.hibernate.NonUniqueResultException;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.envers.ModifiedEntityTypes;
|
||||
import org.hibernate.envers.RevisionType;
|
||||
import org.hibernate.envers.configuration.AuditConfiguration;
|
||||
import org.hibernate.envers.exception.AuditException;
|
||||
|
@ -43,7 +42,6 @@ import org.hibernate.envers.query.AuditEntity;
|
|||
import org.hibernate.envers.query.AuditQueryCreator;
|
||||
import org.hibernate.envers.query.criteria.RevisionTypeAuditExpression;
|
||||
import org.hibernate.envers.synchronization.AuditProcess;
|
||||
import org.hibernate.envers.tools.reflection.ReflectionTools;
|
||||
import org.hibernate.event.EventSource;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
|
||||
|
@ -294,22 +292,7 @@ public class AuditReaderImpl implements AuditReaderImplementor {
|
|||
Object revisionInfo = query.uniqueResult();
|
||||
if (revisionInfo != null) {
|
||||
// If revision exists
|
||||
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 {
|
||||
result.add(Class.forName(entityClassName));
|
||||
} catch (ClassNotFoundException e) {
|
||||
// This shall never happen
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return verCfg.getModifiedEntityTypesReader().getModifiedEntityTypes(revisionInfo);
|
||||
}
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package org.hibernate.envers.revisioninfo;
|
||||
|
||||
import org.hibernate.envers.entities.PropertyData;
|
||||
import org.hibernate.envers.tools.reflection.ReflectionTools;
|
||||
import org.hibernate.property.Getter;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Returns modified entity types from a persisted revision info entity.
|
||||
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||
*/
|
||||
public class ModifiedEntityTypesReader {
|
||||
private final Getter modifiedEntityTypesGetter;
|
||||
|
||||
public ModifiedEntityTypesReader(Class<?> revisionInfoClass, PropertyData modifiedEntityTypesData) {
|
||||
modifiedEntityTypesGetter = ReflectionTools.getGetter(revisionInfoClass, modifiedEntityTypesData);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public Set<Class> getModifiedEntityTypes(Object revisionEntity) {
|
||||
// The default mechanism of tracking entity types that have been changed during each revision, stores
|
||||
// fully qualified Java class names.
|
||||
Set<String> modifiedEntityClassNames = (Set<String>) modifiedEntityTypesGetter.get(revisionEntity);
|
||||
if (modifiedEntityClassNames != null) {
|
||||
Set<Class> result = new HashSet<Class>(modifiedEntityClassNames.size());
|
||||
for (String entityClassName : modifiedEntityClassNames) {
|
||||
try {
|
||||
result.add(Thread.currentThread().getContextClassLoader().loadClass(entityClassName));
|
||||
} catch (ClassNotFoundException e) {
|
||||
// This shall never happen
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
}
|
|
@ -45,7 +45,6 @@ import static org.hibernate.envers.tools.Pair.make;
|
|||
|
||||
/**
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||
*/
|
||||
public class ReflectionTools {
|
||||
private static final Map<Pair<Class, String>, Getter> getterCache =
|
||||
|
@ -100,91 +99,4 @@ public class ReflectionTools {
|
|||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 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(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.add(field);
|
||||
}
|
||||
for (Method method : annotatedMethods) {
|
||||
method.setAccessible(true);
|
||||
result.add(method);
|
||||
}
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates {@code fields} set with all properties marked with a given annotation.
|
||||
* @param clazz Class type.
|
||||
* @param annotation Annotation.
|
||||
* @param fields Set of annotated fields. Shall be initialized externally.
|
||||
*/
|
||||
private static void doGetAnnotatedFields(Class clazz, Class<? extends Annotation> annotation, Set<Field> fields) {
|
||||
for (Field field : clazz.getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
if (field.isAnnotationPresent(annotation)) {
|
||||
fields.add(field);
|
||||
}
|
||||
}
|
||||
Class superClass = clazz.getSuperclass();
|
||||
if (!Object.class.equals(superClass)) {
|
||||
doGetAnnotatedFields(superClass, annotation, fields);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates {@code methods} set with all functions marked with a given annotation.
|
||||
* @param clazz Class type.
|
||||
* @param annotation Annotation.
|
||||
* @param methods Set of annotated methods. Shall be initialized externally.
|
||||
*/
|
||||
private static void doGetAnnotatedMethods(Class clazz, Class<? extends Annotation> annotation, Set<Method> methods) {
|
||||
for (Method method : clazz.getDeclaredMethods()) {
|
||||
method.setAccessible(true);
|
||||
if (method.isAnnotationPresent(annotation)) {
|
||||
methods.add(method);
|
||||
}
|
||||
}
|
||||
Class superClass = clazz.getSuperclass();
|
||||
if (!Object.class.equals(superClass)) {
|
||||
doGetAnnotatedMethods(superClass, annotation, methods);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue