HHH-5580 - Moving queries from AuditReader to EntitiesChangedInRevisionManager
This commit is contained in:
parent
83ba7be3a3
commit
587c228973
|
@ -800,25 +800,25 @@ query.add(AuditEntity.relatedId("address").eq(relatedEntityId));]]></programlist
|
||||||
The basic query allows retrieving entity names and corresponding Java classes changed in a specified revision:
|
The basic query allows retrieving entity names and corresponding Java classes changed in a specified revision:
|
||||||
</para>
|
</para>
|
||||||
<programlisting><![CDATA[Set<Pair<String, Class>> modifiedEntityTypes = getAuditReader()
|
<programlisting><![CDATA[Set<Pair<String, Class>> modifiedEntityTypes = getAuditReader()
|
||||||
.findEntityTypesChangedInRevision(revisionNumber);]]></programlisting>
|
.getEntitiesChangedInRevisionManager().findEntityTypes(revisionNumber);]]></programlisting>
|
||||||
<para>
|
<para>
|
||||||
Other queries (accessible from <interfacename>org.hibernate.envers.AuditReader</interfacename>):
|
Other queries (also accessible from <interfacename>org.hibernate.envers.EntitiesChangedInRevisionManager</interfacename>):
|
||||||
</para>
|
</para>
|
||||||
<orderedlist>
|
<orderedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<firstterm><methodname>List<![CDATA[<Object>]]> findEntitiesChangedInRevision(Number)</methodname></firstterm>
|
<firstterm><methodname>List<![CDATA[<Object>]]> findEntities(Number)</methodname></firstterm>
|
||||||
- Returns snapshots of all audited entities changed (added, updated and removed) in a given revision.
|
- Returns snapshots of all audited entities changed (added, updated and removed) in a given revision.
|
||||||
Executes <literal>n+1</literal> SQL queries, where <literal>n</literal> is a number of different entity
|
Executes <literal>n+1</literal> SQL queries, where <literal>n</literal> is a number of different entity
|
||||||
classes modified within specified revision.
|
classes modified within specified revision.
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<firstterm><methodname>List<![CDATA[<Object>]]> findEntitiesChangedInRevision(Number, RevisionType)</methodname></firstterm>
|
<firstterm><methodname>List<![CDATA[<Object>]]> findEntities(Number, RevisionType)</methodname></firstterm>
|
||||||
- Returns snapshots of all audited entities changed (added, updated or removed) in a given revision
|
- Returns snapshots of all audited entities changed (added, updated or removed) in a given revision
|
||||||
filtered by modification type. Executes <literal>n+1</literal> SQL queries, where <literal>n</literal>
|
filtered by modification type. Executes <literal>n+1</literal> SQL queries, where <literal>n</literal>
|
||||||
is a number of different entity classes modified within specified revision.
|
is a number of different entity classes modified within specified revision.
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<firstterm><methodname><![CDATA[Map<RevisionType, List<Object>>]]> findEntitiesChangedInRevisionGroupByRevisionType(Number)</methodname></firstterm>
|
<firstterm><methodname><![CDATA[Map<RevisionType, List<Object>>]]> findEntitiesGroupByRevisionType(Number)</methodname></firstterm>
|
||||||
- Returns a map containing lists of entity snapshots grouped by modification operation (e.g.
|
- Returns a map containing lists of entity snapshots grouped by modification operation (e.g.
|
||||||
addition, update and removal). Executes <literal>3n+1</literal> SQL queries, where <literal>n</literal>
|
addition, update and removal). Executes <literal>3n+1</literal> SQL queries, where <literal>n</literal>
|
||||||
is a number of different entity classes modified within specified revision.
|
is a number of different entity classes modified within specified revision.
|
||||||
|
|
|
@ -28,7 +28,6 @@ import org.hibernate.envers.exception.AuditException;
|
||||||
import org.hibernate.envers.exception.NotAuditedException;
|
import org.hibernate.envers.exception.NotAuditedException;
|
||||||
import org.hibernate.envers.exception.RevisionDoesNotExistException;
|
import org.hibernate.envers.exception.RevisionDoesNotExistException;
|
||||||
import org.hibernate.envers.query.AuditQueryCreator;
|
import org.hibernate.envers.query.AuditQueryCreator;
|
||||||
import org.hibernate.envers.tools.Pair;
|
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -212,12 +211,8 @@ public interface AuditReader {
|
||||||
throws HibernateException;
|
throws HibernateException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find all entities changed (added, updated and removed) in a given revision. Executes <i>n+1</i> SQL queries,
|
* @return Basic implementation of {@link EntitiesChangedInRevisionManager} interface. Raises an exception if the default
|
||||||
* where <i>n</i> is a number of different entity classes modified within specified revision.
|
* mechanism of tracking entity names modified during revisions has not been enabled.
|
||||||
* @param revision Revision number.
|
|
||||||
* @return Snapshots of all audited entities changed in a given revision.
|
|
||||||
* @throws IllegalStateException If the associated entity manager is closed.
|
|
||||||
* @throws IllegalArgumentException If a revision number is <code>null</code>, less or equal to 0.
|
|
||||||
* @throws AuditException If none of the following conditions is satisfied:
|
* @throws AuditException If none of the following conditions is satisfied:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li><code>org.hibernate.envers.track_entities_changed_in_revision</code>
|
* <li><code>org.hibernate.envers.track_entities_changed_in_revision</code>
|
||||||
|
@ -228,70 +223,5 @@ public interface AuditReader {
|
||||||
* marked with {@link ModifiedEntityNames} interface.</li>
|
* marked with {@link ModifiedEntityNames} interface.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
List<Object> findEntitiesChangedInRevision(Number revision)
|
public EntitiesChangedInRevisionManager getEntitiesChangedInRevisionManager() throws AuditException;
|
||||||
throws IllegalStateException, IllegalArgumentException, AuditException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find all entities changed (added, updated or removed) in a given revision. Executes <i>n+1</i> SQL queries,
|
|
||||||
* where <i>n</i> is a number of different entity classes modified within specified revision.
|
|
||||||
* @param revision Revision number.
|
|
||||||
* @param revisionType Type of modification.
|
|
||||||
* @return Snapshots of all audited entities changed in a given revision and filtered by modification type.
|
|
||||||
* @throws IllegalStateException If the associated entity manager is closed.
|
|
||||||
* @throws IllegalArgumentException If a revision number is {@code null}, less or equal to 0.
|
|
||||||
* @throws AuditException If none of the following conditions is satisfied:
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code org.hibernate.envers.track_entities_changed_in_revision}
|
|
||||||
* parameter is set to {@code true}.</li>
|
|
||||||
* <li>Custom revision entity (annotated with {@link RevisionEntity})
|
|
||||||
* extends {@link DefaultTrackingModifiedEntitiesRevisionEntity} base class.</li>
|
|
||||||
* <li>Custom revision entity (annotated with {@link RevisionEntity}) encapsulates a field
|
|
||||||
* marked with {@link ModifiedEntityNames} interface.</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
List<Object> findEntitiesChangedInRevision(Number revision, RevisionType revisionType)
|
|
||||||
throws IllegalStateException, IllegalArgumentException, AuditException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find all entities changed (added, updated and removed) in a given revision grouped by modification type.
|
|
||||||
* Executes <i>mn+1</i> SQL queries, where:
|
|
||||||
* <ul>
|
|
||||||
* <li><i>n</i> - number of different entity classes modified within specified revision.
|
|
||||||
* <li><i>m</i> - number of different revision types. See {@link RevisionType} enum.
|
|
||||||
* </ul>
|
|
||||||
* @param revision Revision number.
|
|
||||||
* @return Map containing lists of entity snapshots grouped by modification operation (e.g. addition, update, removal).
|
|
||||||
* @throws IllegalStateException If the associated entity manager is closed.
|
|
||||||
* @throws IllegalArgumentException If a revision number is {@code null}, less or equal to 0.
|
|
||||||
* @throws AuditException If none of the following conditions is satisfied:
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code org.hibernate.envers.track_entities_changed_in_revision}
|
|
||||||
* parameter is set to {@code true}.</li>
|
|
||||||
* <li>Custom revision entity (annotated with {@link RevisionEntity})
|
|
||||||
* extends {@link DefaultTrackingModifiedEntitiesRevisionEntity} base class.</li>
|
|
||||||
* <li>Custom revision entity (annotated with {@link RevisionEntity}) encapsulates a field
|
|
||||||
* marked with {@link ModifiedEntityNames} interface.</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
Map<RevisionType, List<Object>> findEntitiesChangedInRevisionGroupByRevisionType(Number revision)
|
|
||||||
throws IllegalStateException, IllegalArgumentException, AuditException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns set of entity names and corresponding Java classes modified in a given revision.
|
|
||||||
* @param revision Revision number.
|
|
||||||
* @return Set of entity names and corresponding Java classes modified in a given revision.
|
|
||||||
* @throws IllegalStateException If the associated entity manager is closed.
|
|
||||||
* @throws IllegalArgumentException If a revision number is {@code null}, less or equal to 0.
|
|
||||||
* @throws AuditException If none of the following conditions is satisfied:
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code org.hibernate.envers.track_entities_changed_in_revision}
|
|
||||||
* parameter is set to {@code true}.</li>
|
|
||||||
* <li>Custom revision entity (annotated with {@link RevisionEntity})
|
|
||||||
* extends {@link DefaultTrackingModifiedEntitiesRevisionEntity} base class.</li>
|
|
||||||
* <li>Custom revision entity (annotated with {@link RevisionEntity}) encapsulates a field
|
|
||||||
* marked with {@link ModifiedEntityNames} interface.</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
Set<Pair<String, Class>> findEntityTypesChangedInRevision(Number revision)
|
|
||||||
throws IllegalStateException, IllegalArgumentException, AuditException;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
package org.hibernate.envers;
|
||||||
|
|
||||||
|
import org.hibernate.envers.tools.Pair;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries that allow retrieving snapshots of all entities (regardless of their particular type) changed in the given
|
||||||
|
* revision. Note that this API can be legally used only when default mechanism of tracking modified entity names
|
||||||
|
* is enabled.
|
||||||
|
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||||
|
*/
|
||||||
|
public interface EntitiesChangedInRevisionManager {
|
||||||
|
/**
|
||||||
|
* Find all entities changed (added, updated and removed) in a given revision. Executes <i>n+1</i> SQL queries,
|
||||||
|
* where <i>n</i> is a number of different entity classes modified within specified revision.
|
||||||
|
* @param revision Revision number.
|
||||||
|
* @return Snapshots of all audited entities changed in a given revision.
|
||||||
|
* @throws IllegalStateException If the associated entity manager is closed.
|
||||||
|
* @throws IllegalArgumentException If a revision number is <code>null</code>, less or equal to 0.
|
||||||
|
*/
|
||||||
|
public List<Object> findEntities(Number revision) throws IllegalStateException, IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all entities changed (added, updated or removed) in a given revision. Executes <i>n+1</i> SQL queries,
|
||||||
|
* where <i>n</i> is a number of different entity classes modified within specified revision.
|
||||||
|
* @param revision Revision number.
|
||||||
|
* @param revisionType Type of modification.
|
||||||
|
* @return Snapshots of all audited entities changed in a given revision and filtered by modification type.
|
||||||
|
* @throws IllegalStateException If the associated entity manager is closed.
|
||||||
|
* @throws IllegalArgumentException If a revision number is {@code null}, less or equal to 0.
|
||||||
|
*/
|
||||||
|
public List<Object> findEntities(Number revision, RevisionType revisionType) throws IllegalStateException,
|
||||||
|
IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all entities changed (added, updated and removed) in a given revision grouped by modification type.
|
||||||
|
* Executes <i>mn+1</i> SQL queries, where:
|
||||||
|
* <ul>
|
||||||
|
* <li><i>n</i> - number of different entity classes modified within specified revision.
|
||||||
|
* <li><i>m</i> - number of different revision types. See {@link RevisionType} enum.
|
||||||
|
* </ul>
|
||||||
|
* @param revision Revision number.
|
||||||
|
* @return Map containing lists of entity snapshots grouped by modification operation (e.g. addition, update, removal).
|
||||||
|
* @throws IllegalStateException If the associated entity manager is closed.
|
||||||
|
* @throws IllegalArgumentException If a revision number is {@code null}, less or equal to 0.
|
||||||
|
*/
|
||||||
|
public Map<RevisionType, List<Object>> findEntitiesGroupByRevisionType(Number revision) throws IllegalStateException,
|
||||||
|
IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns set of entity names and corresponding Java classes modified in a given revision.
|
||||||
|
* @param revision Revision number.
|
||||||
|
* @return Set of entity names and corresponding Java classes modified in a given revision.
|
||||||
|
* @throws IllegalStateException If the associated entity manager is closed.
|
||||||
|
* @throws IllegalArgumentException If a revision number is {@code null}, less or equal to 0.
|
||||||
|
*/
|
||||||
|
public Set<Pair<String, Class>> findEntityTypes(Number revision) throws IllegalStateException, IllegalArgumentException;
|
||||||
|
}
|
|
@ -25,8 +25,6 @@ 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 static org.hibernate.envers.tools.Tools.getTargetClassIfProxied;
|
import static org.hibernate.envers.tools.Tools.getTargetClassIfProxied;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -39,17 +37,14 @@ import org.hibernate.HibernateException;
|
||||||
import org.hibernate.NonUniqueResultException;
|
import org.hibernate.NonUniqueResultException;
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.envers.RevisionType;
|
import org.hibernate.envers.EntitiesChangedInRevisionManager;
|
||||||
import org.hibernate.envers.configuration.AuditConfiguration;
|
import org.hibernate.envers.configuration.AuditConfiguration;
|
||||||
import org.hibernate.envers.exception.AuditException;
|
import org.hibernate.envers.exception.AuditException;
|
||||||
import org.hibernate.envers.exception.NotAuditedException;
|
import org.hibernate.envers.exception.NotAuditedException;
|
||||||
import org.hibernate.envers.exception.RevisionDoesNotExistException;
|
import org.hibernate.envers.exception.RevisionDoesNotExistException;
|
||||||
import org.hibernate.envers.query.AuditEntity;
|
import org.hibernate.envers.query.AuditEntity;
|
||||||
import org.hibernate.envers.query.AuditQueryCreator;
|
import org.hibernate.envers.query.AuditQueryCreator;
|
||||||
import org.hibernate.envers.query.criteria.RevisionTypeAuditExpression;
|
|
||||||
import org.hibernate.envers.synchronization.AuditProcess;
|
import org.hibernate.envers.synchronization.AuditProcess;
|
||||||
import org.hibernate.envers.tools.Pair;
|
|
||||||
import org.hibernate.envers.tools.Tools;
|
|
||||||
import org.hibernate.event.spi.EventSource;
|
import org.hibernate.event.spi.EventSource;
|
||||||
import org.hibernate.proxy.HibernateProxy;
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
|
|
||||||
|
@ -63,6 +58,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 final EntitiesChangedInRevisionManager entitiesChangedInRevisionManager;
|
||||||
|
|
||||||
public AuditReaderImpl(AuditConfiguration verCfg, Session session,
|
public AuditReaderImpl(AuditConfiguration verCfg, Session session,
|
||||||
SessionImplementor sessionImplementor) {
|
SessionImplementor sessionImplementor) {
|
||||||
|
@ -71,6 +67,7 @@ public class AuditReaderImpl implements AuditReaderImplementor {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
|
|
||||||
firstLevelCache = new FirstLevelCache();
|
firstLevelCache = new FirstLevelCache();
|
||||||
|
entitiesChangedInRevisionManager = new EntitiesChangedInRevisionManagerImpl(this, verCfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkSession() {
|
private void checkSession() {
|
||||||
|
@ -247,73 +244,13 @@ public class AuditReaderImpl implements AuditReaderImplementor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked"})
|
public EntitiesChangedInRevisionManager getEntitiesChangedInRevisionManager() throws AuditException {
|
||||||
public List<Object> findEntitiesChangedInRevision(Number revision) throws IllegalStateException,
|
|
||||||
IllegalArgumentException, AuditException {
|
|
||||||
Set<Pair<String, Class>> entityTypes = findEntityTypesChangedInRevision(revision);
|
|
||||||
List<Object> result = new ArrayList<Object>();
|
|
||||||
for (Pair<String, Class> type : entityTypes) {
|
|
||||||
result.addAll(createQuery().forEntitiesModifiedAtRevision(type.getSecond(), type.getFirst(), revision).getResultList());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked"})
|
|
||||||
public List<Object> findEntitiesChangedInRevision(Number revision, RevisionType revisionType)
|
|
||||||
throws IllegalStateException, IllegalArgumentException, AuditException {
|
|
||||||
Set<Pair<String, Class>> entityTypes = findEntityTypesChangedInRevision(revision);
|
|
||||||
List<Object> result = new ArrayList<Object>();
|
|
||||||
for (Pair<String, Class> type : entityTypes) {
|
|
||||||
result.addAll(createQuery().forEntitiesModifiedAtRevision(type.getSecond(), type.getFirst(), revision)
|
|
||||||
.add(new RevisionTypeAuditExpression(revisionType, "=")).getResultList());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked"})
|
|
||||||
public Map<RevisionType, List<Object>> findEntitiesChangedInRevisionGroupByRevisionType(Number revision)
|
|
||||||
throws IllegalStateException, IllegalArgumentException, AuditException {
|
|
||||||
Set<Pair<String, Class>> entityTypes = findEntityTypesChangedInRevision(revision);
|
|
||||||
Map<RevisionType, List<Object>> result = new HashMap<RevisionType, List<Object>>();
|
|
||||||
for (RevisionType revisionType : RevisionType.values()) {
|
|
||||||
result.put(revisionType, new ArrayList<Object>());
|
|
||||||
for (Pair<String, Class> type : entityTypes) {
|
|
||||||
List<Object> list = createQuery().forEntitiesModifiedAtRevision(type.getSecond(), type.getFirst(), revision)
|
|
||||||
.add(new RevisionTypeAuditExpression(revisionType, "=")).getResultList();
|
|
||||||
result.get(revisionType).addAll(list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked"})
|
|
||||||
public Set<Pair<String, Class>> findEntityTypesChangedInRevision(Number revision) throws IllegalStateException,
|
|
||||||
IllegalArgumentException, AuditException {
|
|
||||||
checkNotNull(revision, "Entity revision");
|
|
||||||
checkPositive(revision, "Entity revision");
|
|
||||||
checkSession();
|
|
||||||
if (!verCfg.getGlobalCfg().isTrackEntitiesChangedInRevisionEnabled()) {
|
if (!verCfg.getGlobalCfg().isTrackEntitiesChangedInRevisionEnabled()) {
|
||||||
throw new AuditException("This query is designed for Envers default mechanism of tracking entities modified in a given revision."
|
throw new AuditException("This API is designed for Envers default mechanism of tracking entities modified in a given revision."
|
||||||
+ " Extend DefaultTrackingModifiedEntitiesRevisionEntity, utilize @ModifiedEntityNames annotation or set "
|
+ " Extend DefaultTrackingModifiedEntitiesRevisionEntity, utilize @ModifiedEntityNames annotation or set "
|
||||||
+ "'org.hibernate.envers.track_entities_changed_in_revision' parameter to true.");
|
+ "'org.hibernate.envers.track_entities_changed_in_revision' parameter to true.");
|
||||||
}
|
}
|
||||||
Set<Number> revisions = new HashSet<Number>(1);
|
return entitiesChangedInRevisionManager;
|
||||||
revisions.add(revision);
|
|
||||||
Criteria query = verCfg.getRevisionInfoQueryCreator().getRevisionsQuery(session, revisions);
|
|
||||||
Object revisionInfo = query.uniqueResult();
|
|
||||||
if (revisionInfo != null) {
|
|
||||||
// If revision exists.
|
|
||||||
Set<String> entityNames = verCfg.getModifiedEntityNamesReader().getModifiedEntityNames(revisionInfo);
|
|
||||||
if (entityNames != null) {
|
|
||||||
// Generate result that contains entity names and corresponding Java classes.
|
|
||||||
Set<Pair<String, Class>> result = new HashSet<Pair<String, Class>>();
|
|
||||||
for (String entityName : entityNames) {
|
|
||||||
result.add(Pair.make(entityName, Tools.getEntityClass(sessionImplementor, session, entityName)));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Collections.EMPTY_SET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked"})
|
@SuppressWarnings({"unchecked"})
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
package org.hibernate.envers.reader;
|
||||||
|
|
||||||
|
import org.hibernate.Criteria;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
|
import org.hibernate.envers.EntitiesChangedInRevisionManager;
|
||||||
|
import org.hibernate.envers.RevisionType;
|
||||||
|
import org.hibernate.envers.configuration.AuditConfiguration;
|
||||||
|
import org.hibernate.envers.query.criteria.RevisionTypeAuditExpression;
|
||||||
|
import org.hibernate.envers.tools.Pair;
|
||||||
|
import org.hibernate.envers.tools.Tools;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static org.hibernate.envers.tools.ArgumentsTools.checkNotNull;
|
||||||
|
import static org.hibernate.envers.tools.ArgumentsTools.checkPositive;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||||
|
*/
|
||||||
|
public class EntitiesChangedInRevisionManagerImpl implements EntitiesChangedInRevisionManager {
|
||||||
|
private final AuditReaderImplementor auditReaderImplementor;
|
||||||
|
private final AuditConfiguration verCfg;
|
||||||
|
|
||||||
|
public EntitiesChangedInRevisionManagerImpl(AuditReaderImplementor auditReaderImplementor, AuditConfiguration verCfg) {
|
||||||
|
this.auditReaderImplementor = auditReaderImplementor;
|
||||||
|
this.verCfg = verCfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked"})
|
||||||
|
public List<Object> findEntities(Number revision) throws IllegalStateException, IllegalArgumentException {
|
||||||
|
Set<Pair<String, Class>> entityTypes = findEntityTypes(revision);
|
||||||
|
List<Object> result = new ArrayList<Object>();
|
||||||
|
for (Pair<String, Class> type : entityTypes) {
|
||||||
|
result.addAll(auditReaderImplementor.createQuery().forEntitiesModifiedAtRevision(type.getSecond(), type.getFirst(), revision)
|
||||||
|
.getResultList());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked"})
|
||||||
|
public List<Object> findEntities(Number revision, RevisionType revisionType) throws IllegalStateException,
|
||||||
|
IllegalArgumentException {
|
||||||
|
Set<Pair<String, Class>> entityTypes = findEntityTypes(revision);
|
||||||
|
List<Object> result = new ArrayList<Object>();
|
||||||
|
for (Pair<String, Class> type : entityTypes) {
|
||||||
|
result.addAll(auditReaderImplementor.createQuery().forEntitiesModifiedAtRevision(type.getSecond(), type.getFirst(), revision)
|
||||||
|
.add(new RevisionTypeAuditExpression(revisionType, "=")).getResultList());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked"})
|
||||||
|
public Map<RevisionType, List<Object>> findEntitiesGroupByRevisionType(Number revision) throws IllegalStateException,
|
||||||
|
IllegalArgumentException {
|
||||||
|
Set<Pair<String, Class>> entityTypes = findEntityTypes(revision);
|
||||||
|
Map<RevisionType, List<Object>> result = new HashMap<RevisionType, List<Object>>();
|
||||||
|
for (RevisionType revisionType : RevisionType.values()) {
|
||||||
|
result.put(revisionType, new ArrayList<Object>());
|
||||||
|
for (Pair<String, Class> type : entityTypes) {
|
||||||
|
List<Object> list = auditReaderImplementor.createQuery().forEntitiesModifiedAtRevision(type.getSecond(), type.getFirst(), revision)
|
||||||
|
.add(new RevisionTypeAuditExpression(revisionType, "=")).getResultList();
|
||||||
|
result.get(revisionType).addAll(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked"})
|
||||||
|
public Set<Pair<String, Class>> findEntityTypes(Number revision) throws IllegalStateException, IllegalArgumentException {
|
||||||
|
checkNotNull(revision, "Entity revision");
|
||||||
|
checkPositive(revision, "Entity revision");
|
||||||
|
checkSession();
|
||||||
|
|
||||||
|
Session session = auditReaderImplementor.getSession();
|
||||||
|
SessionImplementor sessionImplementor = auditReaderImplementor.getSessionImplementor();
|
||||||
|
|
||||||
|
Set<Number> revisions = new HashSet<Number>(1);
|
||||||
|
revisions.add(revision);
|
||||||
|
Criteria query = verCfg.getRevisionInfoQueryCreator().getRevisionsQuery(session, revisions);
|
||||||
|
Object revisionInfo = query.uniqueResult();
|
||||||
|
|
||||||
|
if (revisionInfo != null) {
|
||||||
|
// If revision exists.
|
||||||
|
Set<String> entityNames = verCfg.getModifiedEntityNamesReader().getModifiedEntityNames(revisionInfo);
|
||||||
|
if (entityNames != null) {
|
||||||
|
// Generate result that contains entity names and corresponding Java classes.
|
||||||
|
Set<Pair<String, Class>> result = new HashSet<Pair<String, Class>>();
|
||||||
|
for (String entityName : entityNames) {
|
||||||
|
result.add(Pair.make(entityName, Tools.getEntityClass(sessionImplementor, session, entityName)));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Collections.EMPTY_SET;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkSession() {
|
||||||
|
if (!auditReaderImplementor.getSession().isOpen()) {
|
||||||
|
throw new IllegalStateException("The associated entity manager is closed!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -100,6 +100,6 @@ public class CustomTrackingEntitiesTest extends AbstractEntityTest {
|
||||||
|
|
||||||
@Test(expected = AuditException.class)
|
@Test(expected = AuditException.class)
|
||||||
public void testFindEntitiesChangedInRevisionException() {
|
public void testFindEntitiesChangedInRevisionException() {
|
||||||
getAuditReader().findEntitiesChangedInRevision(1);
|
getAuditReader().getEntitiesChangedInRevisionManager();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.hibernate.envers.test.integration.reventity.trackmodifiedentities;
|
package org.hibernate.envers.test.integration.reventity.trackmodifiedentities;
|
||||||
|
|
||||||
import org.hibernate.ejb.Ejb3Configuration;
|
import org.hibernate.ejb.Ejb3Configuration;
|
||||||
|
import org.hibernate.envers.EntitiesChangedInRevisionManager;
|
||||||
import org.hibernate.envers.RevisionType;
|
import org.hibernate.envers.RevisionType;
|
||||||
import org.hibernate.envers.test.AbstractEntityTest;
|
import org.hibernate.envers.test.AbstractEntityTest;
|
||||||
import org.hibernate.envers.test.Priority;
|
import org.hibernate.envers.test.Priority;
|
||||||
|
@ -84,14 +85,14 @@ public class DefaultTrackingEntitiesTest extends AbstractEntityTest {
|
||||||
StrTestEntity ste = new StrTestEntity("x", steId);
|
StrTestEntity ste = new StrTestEntity("x", steId);
|
||||||
StrIntTestEntity site = new StrIntTestEntity("y", 1, siteId);
|
StrIntTestEntity site = new StrIntTestEntity("y", 1, siteId);
|
||||||
|
|
||||||
assert TestTools.checkList(getAuditReader().findEntitiesChangedInRevision(1), ste, site);
|
assert TestTools.checkList(getEntitiesChangedInRevisionManager().findEntities(1), ste, site);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTrackModifiedEntities() {
|
public void testTrackModifiedEntities() {
|
||||||
StrIntTestEntity site = new StrIntTestEntity("y", 2, siteId);
|
StrIntTestEntity site = new StrIntTestEntity("y", 2, siteId);
|
||||||
|
|
||||||
assert TestTools.checkList(getAuditReader().findEntitiesChangedInRevision(2), site);
|
assert TestTools.checkList(getEntitiesChangedInRevisionManager().findEntities(2), site);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -99,12 +100,12 @@ public class DefaultTrackingEntitiesTest extends AbstractEntityTest {
|
||||||
StrTestEntity ste = new StrTestEntity(null, steId);
|
StrTestEntity ste = new StrTestEntity(null, steId);
|
||||||
StrIntTestEntity site = new StrIntTestEntity(null, null, siteId);
|
StrIntTestEntity site = new StrIntTestEntity(null, null, siteId);
|
||||||
|
|
||||||
assert TestTools.checkList(getAuditReader().findEntitiesChangedInRevision(3), site, ste);
|
assert TestTools.checkList(getEntitiesChangedInRevisionManager().findEntities(3), site, ste);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFindChangesInInvalidRevision() {
|
public void testFindChangesInInvalidRevision() {
|
||||||
assert getAuditReader().findEntitiesChangedInRevision(4).isEmpty();
|
assert getEntitiesChangedInRevisionManager().findEntities(4).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -112,7 +113,7 @@ public class DefaultTrackingEntitiesTest extends AbstractEntityTest {
|
||||||
StrTestEntity ste = new StrTestEntity("x", steId);
|
StrTestEntity ste = new StrTestEntity("x", steId);
|
||||||
StrIntTestEntity site = new StrIntTestEntity("y", 1, siteId);
|
StrIntTestEntity site = new StrIntTestEntity("y", 1, siteId);
|
||||||
|
|
||||||
Map<RevisionType, List<Object>> result = getAuditReader().findEntitiesChangedInRevisionGroupByRevisionType(1);
|
Map<RevisionType, List<Object>> result = getEntitiesChangedInRevisionManager().findEntitiesGroupByRevisionType(1);
|
||||||
assert TestTools.checkList(result.get(RevisionType.ADD), site, ste);
|
assert TestTools.checkList(result.get(RevisionType.ADD), site, ste);
|
||||||
assert TestTools.checkList(result.get(RevisionType.MOD));
|
assert TestTools.checkList(result.get(RevisionType.MOD));
|
||||||
assert TestTools.checkList(result.get(RevisionType.DEL));
|
assert TestTools.checkList(result.get(RevisionType.DEL));
|
||||||
|
@ -122,7 +123,7 @@ public class DefaultTrackingEntitiesTest extends AbstractEntityTest {
|
||||||
public void testTrackModifiedEntitiesGroupByRevisionType() {
|
public void testTrackModifiedEntitiesGroupByRevisionType() {
|
||||||
StrIntTestEntity site = new StrIntTestEntity("y", 2, siteId);
|
StrIntTestEntity site = new StrIntTestEntity("y", 2, siteId);
|
||||||
|
|
||||||
Map<RevisionType, List<Object>> result = getAuditReader().findEntitiesChangedInRevisionGroupByRevisionType(2);
|
Map<RevisionType, List<Object>> result = getEntitiesChangedInRevisionManager().findEntitiesGroupByRevisionType(2);
|
||||||
assert TestTools.checkList(result.get(RevisionType.ADD));
|
assert TestTools.checkList(result.get(RevisionType.ADD));
|
||||||
assert TestTools.checkList(result.get(RevisionType.MOD), site);
|
assert TestTools.checkList(result.get(RevisionType.MOD), site);
|
||||||
assert TestTools.checkList(result.get(RevisionType.DEL));
|
assert TestTools.checkList(result.get(RevisionType.DEL));
|
||||||
|
@ -133,7 +134,7 @@ public class DefaultTrackingEntitiesTest extends AbstractEntityTest {
|
||||||
StrTestEntity ste = new StrTestEntity(null, steId);
|
StrTestEntity ste = new StrTestEntity(null, steId);
|
||||||
StrIntTestEntity site = new StrIntTestEntity(null, null, siteId);
|
StrIntTestEntity site = new StrIntTestEntity(null, null, siteId);
|
||||||
|
|
||||||
Map<RevisionType, List<Object>> result = getAuditReader().findEntitiesChangedInRevisionGroupByRevisionType(3);
|
Map<RevisionType, List<Object>> result = getEntitiesChangedInRevisionManager().findEntitiesGroupByRevisionType(3);
|
||||||
assert TestTools.checkList(result.get(RevisionType.ADD));
|
assert TestTools.checkList(result.get(RevisionType.ADD));
|
||||||
assert TestTools.checkList(result.get(RevisionType.MOD));
|
assert TestTools.checkList(result.get(RevisionType.MOD));
|
||||||
assert TestTools.checkList(result.get(RevisionType.DEL), site, ste);
|
assert TestTools.checkList(result.get(RevisionType.DEL), site, ste);
|
||||||
|
@ -144,14 +145,14 @@ public class DefaultTrackingEntitiesTest extends AbstractEntityTest {
|
||||||
StrTestEntity ste = new StrTestEntity("x", steId);
|
StrTestEntity ste = new StrTestEntity("x", steId);
|
||||||
StrIntTestEntity site = new StrIntTestEntity("y", 1, siteId);
|
StrIntTestEntity site = new StrIntTestEntity("y", 1, siteId);
|
||||||
|
|
||||||
assert TestTools.checkList(getAuditReader().findEntitiesChangedInRevision(1, RevisionType.ADD), ste, site);
|
assert TestTools.checkList(getEntitiesChangedInRevisionManager().findEntities(1, RevisionType.ADD), ste, site);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFindChangedEntitiesByRevisionTypeMOD() {
|
public void testFindChangedEntitiesByRevisionTypeMOD() {
|
||||||
StrIntTestEntity site = new StrIntTestEntity("y", 2, siteId);
|
StrIntTestEntity site = new StrIntTestEntity("y", 2, siteId);
|
||||||
|
|
||||||
assert TestTools.checkList(getAuditReader().findEntitiesChangedInRevision(2, RevisionType.MOD), site);
|
assert TestTools.checkList(getEntitiesChangedInRevisionManager().findEntities(2, RevisionType.MOD), site);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -159,20 +160,24 @@ public class DefaultTrackingEntitiesTest extends AbstractEntityTest {
|
||||||
StrTestEntity ste = new StrTestEntity(null, steId);
|
StrTestEntity ste = new StrTestEntity(null, steId);
|
||||||
StrIntTestEntity site = new StrIntTestEntity(null, null, siteId);
|
StrIntTestEntity site = new StrIntTestEntity(null, null, siteId);
|
||||||
|
|
||||||
assert TestTools.checkList(getAuditReader().findEntitiesChangedInRevision(3, RevisionType.DEL), ste, site);
|
assert TestTools.checkList(getEntitiesChangedInRevisionManager().findEntities(3, RevisionType.DEL), ste, site);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFindEntityTypesChangedInRevision() {
|
public void testFindEntityTypesChangedInRevision() {
|
||||||
assert TestTools.makeSet(Pair.make(StrTestEntity.class.getName(), StrTestEntity.class),
|
assert TestTools.makeSet(Pair.make(StrTestEntity.class.getName(), StrTestEntity.class),
|
||||||
Pair.make(StrIntTestEntity.class.getName(), StrIntTestEntity.class))
|
Pair.make(StrIntTestEntity.class.getName(), StrIntTestEntity.class))
|
||||||
.equals(getAuditReader().findEntityTypesChangedInRevision(1));
|
.equals(getEntitiesChangedInRevisionManager().findEntityTypes(1));
|
||||||
|
|
||||||
assert TestTools.makeSet(Pair.make(StrIntTestEntity.class.getName(), StrIntTestEntity.class))
|
assert TestTools.makeSet(Pair.make(StrIntTestEntity.class.getName(), StrIntTestEntity.class))
|
||||||
.equals(getAuditReader().findEntityTypesChangedInRevision(2));
|
.equals(getEntitiesChangedInRevisionManager().findEntityTypes(2));
|
||||||
|
|
||||||
assert TestTools.makeSet(Pair.make(StrTestEntity.class.getName(), StrTestEntity.class),
|
assert TestTools.makeSet(Pair.make(StrTestEntity.class.getName(), StrTestEntity.class),
|
||||||
Pair.make(StrIntTestEntity.class.getName(), StrIntTestEntity.class))
|
Pair.make(StrIntTestEntity.class.getName(), StrIntTestEntity.class))
|
||||||
.equals(getAuditReader().findEntityTypesChangedInRevision(3));
|
.equals(getEntitiesChangedInRevisionManager().findEntityTypes(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
private EntitiesChangedInRevisionManager getEntitiesChangedInRevisionManager() {
|
||||||
|
return getAuditReader().getEntitiesChangedInRevisionManager();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,9 +64,9 @@ public class EntityNamesTest extends AbstractSessionTest {
|
||||||
public void testModifiedEntityTypes() {
|
public void testModifiedEntityTypes() {
|
||||||
assert TestTools.makeSet(Pair.make(Car.class.getName(), Car.class),
|
assert TestTools.makeSet(Pair.make(Car.class.getName(), Car.class),
|
||||||
Pair.make("Personaje", Person.class))
|
Pair.make("Personaje", Person.class))
|
||||||
.equals(getAuditReader().findEntityTypesChangedInRevision(1));
|
.equals(getAuditReader().getEntitiesChangedInRevisionManager().findEntityTypes(1));
|
||||||
assert TestTools.makeSet(Pair.make(Car.class.getName(), Car.class),
|
assert TestTools.makeSet(Pair.make(Car.class.getName(), Car.class),
|
||||||
Pair.make("Personaje", Person.class))
|
Pair.make("Personaje", Person.class))
|
||||||
.equals(getAuditReader().findEntityTypesChangedInRevision(2));
|
.equals(getAuditReader().getEntitiesChangedInRevisionManager().findEntityTypes(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package org.hibernate.envers.test.integration.reventity.trackmodifiedentities;
|
package org.hibernate.envers.test.integration.reventity.trackmodifiedentities;
|
||||||
|
|
||||||
import org.hibernate.ejb.Ejb3Configuration;
|
import org.hibernate.ejb.Ejb3Configuration;
|
||||||
|
import org.hibernate.envers.EntitiesChangedInRevisionManager;
|
||||||
import org.hibernate.envers.test.AbstractEntityTest;
|
import org.hibernate.envers.test.AbstractEntityTest;
|
||||||
import org.hibernate.envers.test.Priority;
|
import org.hibernate.envers.test.Priority;
|
||||||
import org.hibernate.envers.test.entities.StrTestEntity;
|
import org.hibernate.envers.test.entities.StrTestEntity;
|
||||||
|
@ -59,7 +60,7 @@ public class TrackingEntitiesMultipleChangesTest extends AbstractEntityTest {
|
||||||
StrTestEntity ste1 = new StrTestEntity("x", steId1);
|
StrTestEntity ste1 = new StrTestEntity("x", steId1);
|
||||||
StrTestEntity ste2 = new StrTestEntity("y", steId2);
|
StrTestEntity ste2 = new StrTestEntity("y", steId2);
|
||||||
|
|
||||||
assert Arrays.asList(ste1, ste2).equals(getAuditReader().findEntitiesChangedInRevision(1));
|
assert Arrays.asList(ste1, ste2).equals(getEntitiesChangedInRevisionManager().findEntities(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -67,13 +68,17 @@ public class TrackingEntitiesMultipleChangesTest extends AbstractEntityTest {
|
||||||
StrTestEntity ste1 = new StrTestEntity("z", steId1);
|
StrTestEntity ste1 = new StrTestEntity("z", steId1);
|
||||||
StrTestEntity ste2 = new StrTestEntity(null, steId2);
|
StrTestEntity ste2 = new StrTestEntity(null, steId2);
|
||||||
|
|
||||||
assert Arrays.asList(ste1, ste2).equals(getAuditReader().findEntitiesChangedInRevision(2));
|
assert Arrays.asList(ste1, ste2).equals(getEntitiesChangedInRevisionManager().findEntities(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTrackUpdateAndRemoveTheSameEntity() {
|
public void testTrackUpdateAndRemoveTheSameEntity() {
|
||||||
StrTestEntity ste1 = new StrTestEntity(null, steId1);
|
StrTestEntity ste1 = new StrTestEntity(null, steId1);
|
||||||
|
|
||||||
assert Arrays.asList(ste1).equals(getAuditReader().findEntitiesChangedInRevision(3));
|
assert Arrays.asList(ste1).equals(getEntitiesChangedInRevisionManager().findEntities(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
private EntitiesChangedInRevisionManager getEntitiesChangedInRevisionManager() {
|
||||||
|
return getAuditReader().getEntitiesChangedInRevisionManager();
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue