Skip to content

Commit 516577e

Browse files
HHH-7827 - Correlating aggregated and outer queries
1 parent 21ade0c commit 516577e

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed

hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AggregatedAuditExpression.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,13 @@
3232

3333
/**
3434
* @author Adam Warski (adam at warski dot org)
35+
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
3536
*/
3637
public class AggregatedAuditExpression implements AuditCriterion, ExtendableCriterion {
3738
private PropertyNameGetter propertyNameGetter;
3839
private AggregatedMode mode;
40+
// Correlate subquery with outer query by entity id.
41+
private boolean correlate = false;
3942
private List<AuditCriterion> criterions;
4043

4144
public AggregatedAuditExpression(PropertyNameGetter propertyNameGetter, AggregatedMode mode) {
@@ -80,7 +83,26 @@ public void addToQuery(AuditConfiguration auditCfg, String entityName, QueryBuil
8083
subQb.addProjection("max", propertyName, false);
8184
}
8285

86+
// Correlating subquery with the outer query by entity id. See JIRA HHH-7827.
87+
if ( correlate ) {
88+
final String originalIdPropertyName = auditCfg.getAuditEntCfg().getOriginalIdPropName();
89+
auditCfg.getEntCfg().get( entityName ).getIdMapper().addIdsEqualToQuery(
90+
subQb.getRootParameters(),
91+
subQb.getRootAlias() + "." + originalIdPropertyName,
92+
qb.getRootAlias() + "." + originalIdPropertyName
93+
);
94+
}
95+
8396
// Adding the constrain on the result of the aggregated criteria
8497
subParams.addWhere(propertyName, "=", subQb);
8598
}
99+
100+
/**
101+
* Correlates aggregated subquery with the main query by entity id.
102+
* @return this (for method chaining).
103+
*/
104+
public AggregatedAuditExpression correlateSubquery() {
105+
correlate = true;
106+
return this;
107+
}
86108
}

hibernate-envers/src/main/java/org/hibernate/envers/tools/query/QueryBuilder.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,10 @@ private List<String> getAliasList() {
182182
return aliasList;
183183
}
184184

185+
public String getRootAlias() {
186+
return alias;
187+
}
188+
185189
private List<String> getFromList() {
186190
List<String> fromList = new ArrayList<String>();
187191
for (Pair<String, String> from : froms) {

hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/MaximalizePropertyQuery.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030

3131
import javax.persistence.EntityManager;
3232

33+
import org.hibernate.envers.RevisionType;
34+
import org.hibernate.envers.enhanced.SequenceIdRevisionEntity;
3335
import org.hibernate.envers.query.AuditEntity;
3436
import org.hibernate.envers.query.criteria.AuditDisjunction;
3537
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
@@ -42,12 +44,14 @@
4244

4345
/**
4446
* @author Adam Warski (adam at warski dot org)
47+
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
4548
*/
4649
@SuppressWarnings({"unchecked"})
4750
public class MaximalizePropertyQuery extends BaseEnversJPAFunctionalTestCase {
4851
Integer id1;
4952
Integer id2;
5053
Integer id3;
54+
Integer id4;
5155

5256
@Override
5357
protected Class<?>[] getAnnotatedClasses() {
@@ -64,14 +68,17 @@ public void initData() {
6468
StrIntTestEntity site1 = new StrIntTestEntity("a", 10);
6569
StrIntTestEntity site2 = new StrIntTestEntity("b", 15);
6670
StrIntTestEntity site3 = new StrIntTestEntity("c", 42);
71+
StrIntTestEntity site4 = new StrIntTestEntity("d", 52);
6772

6873
em.persist(site1);
6974
em.persist(site2);
7075
em.persist(site3);
76+
em.persist(site4);
7177

7278
id1 = site1.getId();
7379
id2 = site2.getId();
7480
id3 = site3.getId();
81+
id4 = site4.getId();
7582

7683
em.getTransaction().commit();
7784

@@ -107,6 +114,12 @@ public void initData() {
107114
site2.setStr1("a");
108115

109116
em.getTransaction().commit();
117+
118+
// Revision 5
119+
em.getTransaction().begin();
120+
site4 = em.find( StrIntTestEntity.class, id4 );
121+
em.remove( site4 );
122+
em.getTransaction().commit();
110123
}
111124

112125
@Test
@@ -170,4 +183,32 @@ public void testMaximizeInDisjunction() {
170183
}
171184
}
172185
}
186+
187+
@Test
188+
@TestForIssue(jiraKey = "HHH-7827")
189+
public void testAllLatestRevisionsOfEntityType() {
190+
List result = getAuditReader().createQuery()
191+
.forRevisionsOfEntity( StrIntTestEntity.class, false, true )
192+
.add( AuditEntity.revisionNumber().maximize().correlateSubquery() )
193+
.addOrder( AuditEntity.property( "id" ).asc() )
194+
.getResultList();
195+
196+
Assert.assertEquals( 4, result.size() );
197+
198+
Object[] result1 = (Object[]) result.get( 0 );
199+
Object[] result2 = (Object[]) result.get( 1 );
200+
Object[] result3 = (Object[]) result.get( 2 );
201+
Object[] result4 = (Object[]) result.get( 3 );
202+
203+
checkRevisionData( result1, 4, RevisionType.MOD, new StrIntTestEntity( "d", 5, id1 ) );
204+
checkRevisionData( result2, 4, RevisionType.MOD, new StrIntTestEntity( "a", 20, id2 ) );
205+
checkRevisionData( result3, 1, RevisionType.ADD, new StrIntTestEntity( "c", 42, id3 ) );
206+
checkRevisionData( result4, 5, RevisionType.DEL, new StrIntTestEntity( null, null, id4 ) );
207+
}
208+
209+
private void checkRevisionData(Object[] result, int revision, RevisionType type, StrIntTestEntity entity) {
210+
Assert.assertEquals( entity, result[0] );
211+
Assert.assertEquals( revision, ( (SequenceIdRevisionEntity) result[1] ).getId() );
212+
Assert.assertEquals( type, result[2] );
213+
}
173214
}

0 commit comments

Comments
 (0)