HHH-5499:

Extend AuditReader interface with findRevisions() method
Applying patch by Erik-Berndt Scheper - thanks!

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@20309 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Adam Warski 2010-09-04 07:40:43 +00:00
parent 6299d0845b
commit 28dae5c9f3
8 changed files with 170 additions and 30 deletions

View File

@ -25,6 +25,8 @@ package org.hibernate.envers;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.hibernate.envers.exception.NotAuditedException;
import org.hibernate.envers.exception.RevisionDoesNotExistException;
@ -133,6 +135,25 @@ public interface AuditReader {
<T> T findRevision(Class<T> revisionEntityClass, Number revision) throws IllegalArgumentException,
RevisionDoesNotExistException, IllegalStateException;
/**
* Find a map of revisions using the revision numbers specified.
*
* @param revisionEntityClass
* Class of the revision entity. Should be annotated with
* {@link RevisionEntity}.
* @param revisions
* Revision numbers of the revision for which to get the data.
* @return A map of revision number and the given revision entity.
* @throws IllegalArgumentException
* If a revision number is less or equal to 0 or if the class of
* the revision entity is invalid.
* @throws IllegalStateException
* If the associated entity manager is closed.
*/
<T> Map<Number, T> findRevisions(Class<T> revisionEntityClass,
Set<Number> revisions) throws IllegalArgumentException,
IllegalStateException;
/**
* Gets an instance of the current revision entity, to which any entries in the audit tables will be bound.
* Please note the if {@code persist} is {@code false}, and no audited entities are modified in this session,

View File

@ -23,26 +23,31 @@
*/
package org.hibernate.envers.reader;
import java.util.Date;
import java.util.List;
import javax.persistence.NoResultException;
import org.hibernate.envers.configuration.AuditConfiguration;
import org.hibernate.envers.exception.NotAuditedException;
import org.hibernate.envers.exception.RevisionDoesNotExistException;
import org.hibernate.envers.exception.AuditException;
import org.hibernate.envers.query.AuditEntity;
import org.hibernate.envers.query.AuditQueryCreator;
import static org.hibernate.envers.tools.ArgumentsTools.checkNotNull;
import static org.hibernate.envers.tools.ArgumentsTools.checkPositive;
import org.hibernate.envers.synchronization.AuditProcess;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.NoResultException;
import org.hibernate.HibernateException;
import org.hibernate.NonUniqueResultException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.event.EventSource;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.envers.configuration.AuditConfiguration;
import org.hibernate.envers.exception.AuditException;
import org.hibernate.envers.exception.NotAuditedException;
import org.hibernate.envers.exception.RevisionDoesNotExistException;
import org.hibernate.envers.query.AuditEntity;
import org.hibernate.envers.query.AuditQueryCreator;
import org.hibernate.envers.synchronization.AuditProcess;
import org.hibernate.event.EventSource;
/**
* @author Adam Warski (adam at warski dot org)
@ -190,7 +195,9 @@ public class AuditReaderImpl implements AuditReaderImplementor {
checkPositive(revision, "Entity revision");
checkSession();
Query query = verCfg.getRevisionInfoQueryCreator().getRevisionQuery(session, revision);
Set<Number> revisions = new HashSet<Number>(1);
revisions.add(revision);
Query query = verCfg.getRevisionInfoQueryCreator().getRevisionsQuery(session, revisions);
try {
T revisionData = (T) query.uniqueResult();
@ -205,6 +212,32 @@ public class AuditReaderImpl implements AuditReaderImplementor {
}
}
@SuppressWarnings({"unchecked"})
public <T> Map<Number, T> findRevisions(Class<T> revisionEntityClass, Set<Number> revisions) throws IllegalArgumentException,
IllegalStateException {
Map<Number, T> result = new HashMap<Number, T>(revisions.size());
for (Number revision : revisions) {
checkNotNull(revision, "Entity revision");
checkPositive(revision, "Entity revision");
}
checkSession();
Query query = verCfg.getRevisionInfoQueryCreator().getRevisionsQuery(session, revisions);
try {
List<T> revisionList = query.list();
for (T revision : revisionList) {
Number revNo = verCfg.getRevisionInfoNumberReader().getRevisionNumber(revision);
result.put(revNo, revision);
}
return result;
} catch (HibernateException e) {
throw new AuditException(e);
}
}
@SuppressWarnings({"unchecked"})
public <T> T getCurrentRevision(Class<T> revisionEntityClass, boolean persist) {
if (!(session instanceof EventSource)) {

View File

@ -24,6 +24,7 @@
package org.hibernate.envers.revisioninfo;
import java.util.Date;
import java.util.Set;
import org.hibernate.Query;
import org.hibernate.Session;
@ -34,7 +35,7 @@ import org.hibernate.Session;
public class RevisionInfoQueryCreator {
private final String revisionDateQuery;
private final String revisionNumberForDateQuery;
private final String revisionQuery;
private final String revisionsQuery;
private final boolean timestampAsDate;
public RevisionInfoQueryCreator(String revisionInfoEntityName, String revisionInfoIdName,
@ -53,10 +54,10 @@ public class RevisionInfoQueryCreator {
.append(" rev where ").append(revisionInfoTimestampName).append(" <= :_revision_date")
.toString();
revisionQuery = new StringBuilder()
revisionsQuery = new StringBuilder()
.append("select rev from ").append(revisionInfoEntityName)
.append(" rev where ").append(revisionInfoIdName)
.append(" = :_revision_number")
.append(" in (:_revision_numbers)")
.toString();
}
@ -68,7 +69,7 @@ public class RevisionInfoQueryCreator {
return session.createQuery(revisionNumberForDateQuery).setParameter("_revision_date", timestampAsDate ? date : date.getTime());
}
public Query getRevisionQuery(Session session, Number revision) {
return session.createQuery(revisionQuery).setParameter("_revision_number", revision);
public Query getRevisionsQuery(Session session, Set<Number> revisions) {
return session.createQuery(revisionsQuery).setParameterList("_revision_numbers", revisions);
}
}

View File

@ -25,8 +25,13 @@ package org.hibernate.envers.test.integration.reventity;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.persistence.EntityManager;
import org.hibernate.ejb.Ejb3Configuration;
import org.hibernate.envers.AuditReader;
import org.hibernate.envers.exception.RevisionDoesNotExistException;
import org.hibernate.envers.test.AbstractEntityTest;
@ -35,8 +40,6 @@ import org.hibernate.envers.test.entities.reventity.CustomRevEntity;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.hibernate.ejb.Ejb3Configuration;
/**
* @author Adam Warski (adam at warski dot org)
*/
@ -119,6 +122,20 @@ public class Custom extends AbstractEntityTest {
assert rev2Timestamp <= timestamp3;
}
@Test
public void testFindRevisions() {
AuditReader vr = getAuditReader();
Set<Number> revNumbers = new HashSet<Number>();
revNumbers.add(1);
revNumbers.add(2);
Map<Number, CustomRevEntity> revisionMap = vr.findRevisions(CustomRevEntity.class, revNumbers);
assert(revisionMap.size() == 2);
assert(revisionMap.get(1).equals(vr.findRevision(CustomRevEntity.class, 1)));
assert(revisionMap.get(2).equals(vr.findRevision(CustomRevEntity.class, 2)));
}
@Test
public void testRevisionsCounts() {
assert Arrays.asList(1, 2).equals(getAuditReader().getRevisions(StrTestEntity.class, id));

View File

@ -25,8 +25,13 @@ package org.hibernate.envers.test.integration.reventity;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.persistence.EntityManager;
import org.hibernate.ejb.Ejb3Configuration;
import org.hibernate.envers.AuditReader;
import org.hibernate.envers.exception.RevisionDoesNotExistException;
import org.hibernate.envers.test.AbstractEntityTest;
@ -34,8 +39,6 @@ import org.hibernate.envers.test.entities.StrTestEntity;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.hibernate.ejb.Ejb3Configuration;
/**
* @author Adam Warski (adam at warski dot org)
*/
@ -118,6 +121,20 @@ public class CustomBoxed extends AbstractEntityTest {
assert rev2Timestamp <= timestamp3;
}
@Test
public void testFindRevisions() {
AuditReader vr = getAuditReader();
Set<Number> revNumbers = new HashSet<Number>();
revNumbers.add(1);
revNumbers.add(2);
Map<Number, CustomBoxedRevEntity> revisionMap = vr.findRevisions(CustomBoxedRevEntity.class, revNumbers);
assert(revisionMap.size() == 2);
assert(revisionMap.get(1).equals(vr.findRevision(CustomBoxedRevEntity.class, 1)));
assert(revisionMap.get(2).equals(vr.findRevision(CustomBoxedRevEntity.class, 2)));
}
@Test
public void testRevisionsCounts() {
assert Arrays.asList(1, 2).equals(getAuditReader().getRevisions(StrTestEntity.class, id));
@ -131,4 +148,4 @@ public class CustomBoxed extends AbstractEntityTest {
assert getAuditReader().find(StrTestEntity.class, id, 1).equals(ver1);
assert getAuditReader().find(StrTestEntity.class, id, 2).equals(ver2);
}
}
}

View File

@ -25,8 +25,13 @@ package org.hibernate.envers.test.integration.reventity;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.persistence.EntityManager;
import org.hibernate.ejb.Ejb3Configuration;
import org.hibernate.envers.AuditReader;
import org.hibernate.envers.exception.RevisionDoesNotExistException;
import org.hibernate.envers.test.AbstractEntityTest;
@ -34,8 +39,6 @@ import org.hibernate.envers.test.entities.StrTestEntity;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.hibernate.ejb.Ejb3Configuration;
/**
* @author Adam Warski (adam at warski dot org)
*/
@ -118,6 +121,20 @@ public class Inherited extends AbstractEntityTest {
assert rev2Timestamp <= timestamp3;
}
@Test
public void testFindRevisions() {
AuditReader vr = getAuditReader();
Set<Number> revNumbers = new HashSet<Number>();
revNumbers.add(1);
revNumbers.add(2);
Map<Number, InheritedRevEntity> revisionMap = vr.findRevisions(InheritedRevEntity.class, revNumbers);
assert(revisionMap.size() == 2);
assert(revisionMap.get(1).equals(vr.findRevision(InheritedRevEntity.class, 1)));
assert(revisionMap.get(2).equals(vr.findRevision(InheritedRevEntity.class, 2)));
}
@Test
public void testRevisionsCounts() {
assert Arrays.asList(1, 2).equals(getAuditReader().getRevisions(StrTestEntity.class, id));

View File

@ -25,8 +25,13 @@ package org.hibernate.envers.test.integration.reventity;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.persistence.EntityManager;
import org.hibernate.ejb.Ejb3Configuration;
import org.hibernate.envers.AuditReader;
import org.hibernate.envers.exception.RevisionDoesNotExistException;
import org.hibernate.envers.test.AbstractEntityTest;
@ -34,8 +39,6 @@ import org.hibernate.envers.test.entities.StrTestEntity;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.hibernate.ejb.Ejb3Configuration;
/**
* @author Adam Warski (adam at warski dot org)
*/
@ -131,6 +134,20 @@ public class Listener extends AbstractEntityTest {
assert "data2".equals(rev2Data.getData());
}
@Test
public void testFindRevisions() {
AuditReader vr = getAuditReader();
Set<Number> revNumbers = new HashSet<Number>();
revNumbers.add(1);
revNumbers.add(2);
Map<Number, ListenerRevEntity> revisionMap = vr.findRevisions(ListenerRevEntity.class, revNumbers);
assert(revisionMap.size() == 2);
assert(revisionMap.get(1).equals(vr.findRevision(ListenerRevEntity.class, 1)));
assert(revisionMap.get(2).equals(vr.findRevision(ListenerRevEntity.class, 2)));
}
@Test
public void testRevisionsCounts() {
assert Arrays.asList(1, 2).equals(getAuditReader().getRevisions(StrTestEntity.class, id));

View File

@ -24,16 +24,19 @@
package org.hibernate.envers.test.integration.reventity;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.persistence.EntityManager;
import org.hibernate.ejb.Ejb3Configuration;
import org.hibernate.envers.AuditReader;
import org.hibernate.envers.test.AbstractEntityTest;
import org.hibernate.envers.test.entities.StrTestEntity;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.hibernate.ejb.Ejb3Configuration;
/**
* @author Adam Warski (adam at warski dot org)
*/
@ -70,6 +73,20 @@ public class LongRevNumber extends AbstractEntityTest {
assert vr.findRevision(LongRevNumberRevEntity.class, 2l).getCustomId() == 2l;
}
@Test
public void testFindRevisions() {
AuditReader vr = getAuditReader();
Set<Number> revNumbers = new HashSet<Number>();
revNumbers.add(1l);
revNumbers.add(2l);
Map<Number, LongRevNumberRevEntity> revisionMap = vr.findRevisions(LongRevNumberRevEntity.class, revNumbers);
assert(revisionMap.size() == 2);
assert(revisionMap.get(1l).equals(vr.findRevision(LongRevNumberRevEntity.class, 1l)));
assert(revisionMap.get(2l).equals(vr.findRevision(LongRevNumberRevEntity.class, 2l)));
}
@Test
public void testRevisionsCounts() {
assert Arrays.asList(1l, 2l).equals(getAuditReader().getRevisions(StrTestEntity.class, id));
@ -83,4 +100,4 @@ public class LongRevNumber extends AbstractEntityTest {
assert getAuditReader().find(StrTestEntity.class, id, 1l).equals(ver1);
assert getAuditReader().find(StrTestEntity.class, id, 2l).equals(ver2);
}
}
}