HHH-5580 - Naming and EntitiesModifiedAtRevisionQuery tests
This commit is contained in:
parent
36e0d7eced
commit
4022571196
|
@ -253,8 +253,8 @@
|
||||||
</entry>
|
</entry>
|
||||||
<entry>
|
<entry>
|
||||||
Should entity types, that have been modified during each revision, be tracked. The default
|
Should entity types, that have been modified during each revision, be tracked. The default
|
||||||
implementation creates <literal>REVENTITY</literal> table that stores fully qualified names
|
implementation creates <literal>REVCHANGES</literal> table that stores fully qualified names
|
||||||
of Java classes changed in a specified revision. Single record encapsulates the revision
|
of Java classes modified in a specified revision. Single record encapsulates the revision
|
||||||
identifier (foreign key to <literal>REVINFO</literal> table) and a string value. This
|
identifier (foreign key to <literal>REVINFO</literal> table) and a string value. This
|
||||||
feature shall be used when entity name can be clearly identified by Java class type. Otherwise
|
feature shall be used when entity name can be clearly identified by Java class type. Otherwise
|
||||||
extend <interfacename>org.hibernate.envers.EntityTrackingRevisionListener</interfacename>
|
extend <interfacename>org.hibernate.envers.EntityTrackingRevisionListener</interfacename>
|
||||||
|
@ -470,8 +470,8 @@ public class ExampleListener implements RevisionListener {
|
||||||
<para>
|
<para>
|
||||||
By default entity types that have been changed in each revision are not being tracked. This implies the
|
By default entity types that have been changed in each revision are not being tracked. This implies the
|
||||||
necessity to query all tables storing audited data in order to retrieve changes made during
|
necessity to query all tables storing audited data in order to retrieve changes made during
|
||||||
specified revision. Envers provides a simple mechanism that creates <literal>REVENTITY</literal>
|
specified revision. Envers provides a simple mechanism that creates <literal>REVCHANGES</literal>
|
||||||
table which stores fully qualified names of Java classes changed in each revision.
|
table which stores fully qualified names of Java classes modified in each revision.
|
||||||
Single record encapsulates the revision identifier (foreign key to <literal>REVINFO</literal> table)
|
Single record encapsulates the revision identifier (foreign key to <literal>REVINFO</literal> table)
|
||||||
and a string value. Note that this mechanism shall be used when entity name can be clearly identified
|
and a string value. Note that this mechanism shall be used when entity name can be clearly identified
|
||||||
by Java class type. Otherwise extend <interfacename>org.hibernate.envers.EntityTrackingRevisionListener</interfacename>
|
by Java class type. Otherwise extend <interfacename>org.hibernate.envers.EntityTrackingRevisionListener</interfacename>
|
||||||
|
@ -508,7 +508,7 @@ public class AnnotatedTrackingRevisionEntity {
|
||||||
...
|
...
|
||||||
|
|
||||||
@ElementCollection
|
@ElementCollection
|
||||||
@JoinTable(name = "REVENTITY", joinColumns = @JoinColumn(name = "REV"))
|
@JoinTable(name = "REVCHANGES", joinColumns = @JoinColumn(name = "REV"))
|
||||||
@Column(name = "ENTITYTYPE")
|
@Column(name = "ENTITYTYPE")
|
||||||
@ModifiedEntityTypes
|
@ModifiedEntityTypes
|
||||||
private Set<String> modifiedEntityTypes;
|
private Set<String> modifiedEntityTypes;
|
||||||
|
|
|
@ -16,7 +16,7 @@ import java.util.Set;
|
||||||
@MappedSuperclass
|
@MappedSuperclass
|
||||||
public class DefaultTrackingModifiedTypesRevisionEntity extends DefaultRevisionEntity {
|
public class DefaultTrackingModifiedTypesRevisionEntity extends DefaultRevisionEntity {
|
||||||
@ElementCollection(fetch = FetchType.EAGER)
|
@ElementCollection(fetch = FetchType.EAGER)
|
||||||
@JoinTable(name = "REVENTITY", joinColumns = @JoinColumn(name = "REV"))
|
@JoinTable(name = "REVCHANGES", joinColumns = @JoinColumn(name = "REV"))
|
||||||
@Column(name = "ENTITYTYPE")
|
@Column(name = "ENTITYTYPE")
|
||||||
@Fetch(FetchMode.JOIN)
|
@Fetch(FetchMode.JOIN)
|
||||||
@ModifiedEntityTypes
|
@ModifiedEntityTypes
|
||||||
|
|
|
@ -99,7 +99,7 @@ public class RevisionInfoConfiguration {
|
||||||
MetadataTools.addColumn(timestampProperty, "REVTSTMP", null, 0, 0, null, null, null, false);
|
MetadataTools.addColumn(timestampProperty, "REVTSTMP", null, 0, 0, null, null, null, false);
|
||||||
|
|
||||||
if (globalCfg.isTrackEntitiesChangedInRevisionEnabled()) {
|
if (globalCfg.isTrackEntitiesChangedInRevisionEnabled()) {
|
||||||
generateEntityTypesTrackingTableMapping(class_mapping, "modifiedEntityTypes", "REVENTITY", "REV", "ENTITYTYPE", "string");
|
generateEntityTypesTrackingTableMapping(class_mapping, "modifiedEntityTypes", "REVCHANGES", "REV", "ENTITYTYPE", "string");
|
||||||
}
|
}
|
||||||
|
|
||||||
return document;
|
return document;
|
||||||
|
|
|
@ -79,11 +79,27 @@ public class AuditQueryCreator {
|
||||||
* In comparison to {@link #forEntitiesAtRevision(Class, String, Number)} this query will return an empty
|
* In comparison to {@link #forEntitiesAtRevision(Class, String, Number)} this query will return an empty
|
||||||
* collection if an entity of a certain type has not been changed in a given revision.
|
* collection if an entity of a certain type has not been changed in a given revision.
|
||||||
* @param c Class of the entities for which to query.
|
* @param c Class of the entities for which to query.
|
||||||
|
* @param entityName Name of the entity (if can't be guessed basing on the {@code c}).
|
||||||
* @param revision Revision number at which to execute the query.
|
* @param revision Revision number at which to execute the query.
|
||||||
* @return A query for entities changed at a given revision, to which conditions can be added and which
|
* @return A query for entities changed at a given revision, to which conditions can be added and which
|
||||||
* can then be executed.
|
* can then be executed.
|
||||||
* @see #forEntitiesAtRevision(Class, String, Number)
|
* @see #forEntitiesAtRevision(Class, String, Number)
|
||||||
*/
|
*/
|
||||||
|
public AuditQuery forEntitiesModifiedAtRevision(Class<?> c, String entityName, Number revision) {
|
||||||
|
checkNotNull(revision, "Entity revision");
|
||||||
|
checkPositive(revision, "Entity revision");
|
||||||
|
return new EntitiesModifiedAtRevisionQuery(auditCfg, auditReaderImplementor, c, entityName, revision);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In comparison to {@link #forEntitiesAtRevision(Class, Number)} this query will return an empty
|
||||||
|
* collection if an entity of a certain type has not been changed in a given revision.
|
||||||
|
* @param c Class of the entities for which to query.
|
||||||
|
* @param revision Revision number at which to execute the query.
|
||||||
|
* @return A query for entities changed at a given revision, to which conditions can be added and which
|
||||||
|
* can then be executed.
|
||||||
|
* @see #forEntitiesAtRevision(Class, Number)
|
||||||
|
*/
|
||||||
public AuditQuery forEntitiesModifiedAtRevision(Class<?> c, Number revision) {
|
public AuditQuery forEntitiesModifiedAtRevision(Class<?> c, Number revision) {
|
||||||
checkNotNull(revision, "Entity revision");
|
checkNotNull(revision, "Entity revision");
|
||||||
checkPositive(revision, "Entity revision");
|
checkPositive(revision, "Entity revision");
|
||||||
|
|
|
@ -24,6 +24,12 @@ public class EntitiesModifiedAtRevisionQuery extends AbstractAuditQuery {
|
||||||
this.revision = revision;
|
this.revision = revision;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EntitiesModifiedAtRevisionQuery(AuditConfiguration verCfg, AuditReaderImplementor versionsReader,
|
||||||
|
Class<?> cls, String entityName, Number revision) {
|
||||||
|
super(verCfg, versionsReader, cls, entityName);
|
||||||
|
this.revision = revision;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked"})
|
@SuppressWarnings({"unchecked"})
|
||||||
public List list() {
|
public List list() {
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -24,7 +24,7 @@ public class AnnotatedTrackingRevisionEntity {
|
||||||
private long customTimestamp;
|
private long customTimestamp;
|
||||||
|
|
||||||
@ElementCollection
|
@ElementCollection
|
||||||
@JoinTable(name = "REVENTITY", joinColumns = @JoinColumn(name = "REV"))
|
@JoinTable(name = "REVCHANGES", joinColumns = @JoinColumn(name = "REV"))
|
||||||
@Column(name = "ENTITYTYPE")
|
@Column(name = "ENTITYTYPE")
|
||||||
@ModifiedEntityTypes
|
@ModifiedEntityTypes
|
||||||
private Set<String> entityTypes;
|
private Set<String> entityTypes;
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.hibernate.envers.test.AbstractEntityTest;
|
||||||
import org.hibernate.envers.test.Priority;
|
import org.hibernate.envers.test.Priority;
|
||||||
import org.hibernate.envers.test.entities.StrIntTestEntity;
|
import org.hibernate.envers.test.entities.StrIntTestEntity;
|
||||||
import org.hibernate.envers.test.tools.TestTools;
|
import org.hibernate.envers.test.tools.TestTools;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
|
@ -40,6 +41,7 @@ import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adam Warski (adam at warski dot org)
|
* @author Adam Warski (adam at warski dot org)
|
||||||
|
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"unchecked"})
|
@SuppressWarnings({"unchecked"})
|
||||||
public class SimpleQuery extends AbstractEntityTest {
|
public class SimpleQuery extends AbstractEntityTest {
|
||||||
|
@ -267,4 +269,59 @@ public class SimpleQuery extends AbstractEntityTest {
|
||||||
|
|
||||||
assert result.size() == 0;
|
assert result.size() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEntitiesAddedAtRevision() {
|
||||||
|
StrIntTestEntity site1 = new StrIntTestEntity("a", 10, id1);
|
||||||
|
StrIntTestEntity site2 = new StrIntTestEntity("a", 10, id2);
|
||||||
|
StrIntTestEntity site3 = new StrIntTestEntity("b", 5, id3);
|
||||||
|
|
||||||
|
List result = getAuditReader().createQuery().forEntitiesModifiedAtRevision(StrIntTestEntity.class, StrIntTestEntity.class.getName(), 1).getResultList();
|
||||||
|
RevisionType revisionType = (RevisionType) getAuditReader().createQuery().forEntitiesModifiedAtRevision(StrIntTestEntity.class, 1)
|
||||||
|
.addProjection(AuditEntity.revisionType()).add(AuditEntity.id().eq(id1))
|
||||||
|
.getSingleResult();
|
||||||
|
|
||||||
|
Assert.assertTrue(TestTools.checkList(result, site1, site2, site3));
|
||||||
|
Assert.assertEquals(revisionType, RevisionType.ADD);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEntitiesChangedAtRevision() {
|
||||||
|
StrIntTestEntity site1 = new StrIntTestEntity("c", 10, id1);
|
||||||
|
StrIntTestEntity site2 = new StrIntTestEntity("a", 20, id2);
|
||||||
|
|
||||||
|
List result = getAuditReader().createQuery().forEntitiesModifiedAtRevision(StrIntTestEntity.class, 2).getResultList();
|
||||||
|
RevisionType revisionType = (RevisionType) getAuditReader().createQuery().forEntitiesModifiedAtRevision(StrIntTestEntity.class, 2)
|
||||||
|
.addProjection(AuditEntity.revisionType()).add(AuditEntity.id().eq(id1))
|
||||||
|
.getSingleResult();
|
||||||
|
|
||||||
|
Assert.assertTrue(TestTools.checkList(result, site1, site2));
|
||||||
|
Assert.assertEquals(revisionType, RevisionType.MOD);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEntitiesRemovedAtRevision() {
|
||||||
|
StrIntTestEntity site1 = new StrIntTestEntity(null, null, id1);
|
||||||
|
|
||||||
|
List result = getAuditReader().createQuery().forEntitiesModifiedAtRevision(StrIntTestEntity.class, 4).getResultList();
|
||||||
|
RevisionType revisionType = (RevisionType) getAuditReader().createQuery().forEntitiesModifiedAtRevision(StrIntTestEntity.class, 4)
|
||||||
|
.addProjection(AuditEntity.revisionType()).add(AuditEntity.id().eq(id1))
|
||||||
|
.getSingleResult();
|
||||||
|
|
||||||
|
Assert.assertTrue(TestTools.checkList(result, site1));
|
||||||
|
Assert.assertEquals(revisionType, RevisionType.DEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEntityNotModifiedAtRevision() {
|
||||||
|
List result = getAuditReader().createQuery().forEntitiesModifiedAtRevision(StrIntTestEntity.class, 3)
|
||||||
|
.add(AuditEntity.id().eq(id1)).getResultList();
|
||||||
|
Assert.assertTrue(result.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNoEntitiesModifiedAtRevision() {
|
||||||
|
List result = getAuditReader().createQuery().forEntitiesModifiedAtRevision(StrIntTestEntity.class, 5).getResultList();
|
||||||
|
Assert.assertTrue(result.isEmpty());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ public class DefaultTrackingEntitiesTest extends AbstractEntityTest {
|
||||||
Iterator<Table> tableIterator = getCfg().getTableMappings();
|
Iterator<Table> tableIterator = getCfg().getTableMappings();
|
||||||
while (tableIterator.hasNext()) {
|
while (tableIterator.hasNext()) {
|
||||||
Table table = tableIterator.next();
|
Table table = tableIterator.next();
|
||||||
if ("REVENTITY".equals(table.getName())) {
|
if ("REVCHANGES".equals(table.getName())) {
|
||||||
assert table.getColumnSpan() == 2;
|
assert table.getColumnSpan() == 2;
|
||||||
assert table.getColumn(new Column("REV")) != null;
|
assert table.getColumn(new Column("REV")) != null;
|
||||||
assert table.getColumn(new Column("ENTITYTYPE")) != null;
|
assert table.getColumn(new Column("ENTITYTYPE")) != null;
|
||||||
|
|
Loading…
Reference in New Issue