Skip to content

Commit

Permalink
HHH-11896 Support 'on-clause' criterion when traversing audit query r…
Browse files Browse the repository at this point in the history
…elations
  • Loading branch information
Felix Feisst authored and Naros committed Dec 17, 2021
1 parent e07a8c3 commit 3e3d227
Show file tree
Hide file tree
Showing 5 changed files with 360 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.Incubating;
import org.hibernate.LockMode;
import org.hibernate.envers.exception.AuditException;
import org.hibernate.envers.query.criteria.AuditCriterion;
Expand All @@ -21,7 +22,6 @@

/**
* @author Adam Warski (adam at warski dot org)
* @see org.hibernate.Criteria
*/
public interface AuditQuery {
List getResultList() throws AuditException;
Expand All @@ -30,9 +30,18 @@ public interface AuditQuery {

AuditAssociationQuery<? extends AuditQuery> traverseRelation(String associationName, JoinType joinType);

AuditAssociationQuery<? extends AuditQuery> traverseRelation(String associationName, JoinType joinType,
AuditAssociationQuery<? extends AuditQuery> traverseRelation(
String associationName,
JoinType joinType,
String alias);

@Incubating
AuditAssociationQuery<? extends AuditQuery> traverseRelation(
String associationName,
JoinType joinType,
String alias,
AuditCriterion onClauseCriterion);

AuditQuery add(AuditCriterion criterion);

AuditQuery addProjection(AuditProjection projection);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ public abstract class AbstractAuditQuery implements AuditQueryImplementor {
protected final AuditReaderImplementor versionsReader;

protected final List<AuditAssociationQueryImpl<?>> associationQueries = new ArrayList<>();
protected final Map<String, AuditAssociationQueryImpl<AuditQueryImplementor>> associationQueryMap = new HashMap<>();
protected final List<Pair<String, AuditProjection>> projections = new ArrayList<>();

protected AbstractAuditQuery(
Expand Down Expand Up @@ -196,23 +195,33 @@ public AuditAssociationQuery<? extends AuditQuery> traverseRelation(String assoc

@Override
public AuditAssociationQuery<? extends AuditQuery> traverseRelation(String associationName, JoinType joinType, String alias) {
AuditAssociationQueryImpl<AuditQueryImplementor> result = associationQueryMap.get( associationName );
if (result == null) {
result = new AuditAssociationQueryImpl<>(
enversService,
versionsReader,
this,
qb,
associationName,
joinType,
aliasToEntityNameMap,
aliasToComponentPropertyNameMap,
REFERENCED_ENTITY_ALIAS,
alias
);
associationQueries.add( result );
associationQueryMap.put( associationName, result );
}
return traverseRelation(
associationName,
joinType,
alias,
null );
}

@Override
public AuditAssociationQuery<? extends AuditQuery> traverseRelation(
String associationName,
JoinType joinType,
String alias,
AuditCriterion onClause) {
AuditAssociationQueryImpl<AbstractAuditQuery> result = new AuditAssociationQueryImpl<>(
enversService,
versionsReader,
this,
qb,
associationName,
joinType,
aliasToEntityNameMap,
aliasToComponentPropertyNameMap,
REFERENCED_ENTITY_ALIAS,
alias,
onClause
);
associationQueries.add( result );
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
package org.hibernate.envers.query.internal.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
Expand Down Expand Up @@ -60,9 +59,9 @@ public class AuditAssociationQueryImpl<Q extends AuditQueryImplementor>
private final Map<String, String> aliasToEntityNameMap;
private final Map<String, String> aliasToComponentPropertyNameMap;
private final List<AuditCriterion> criterions = new ArrayList<>();
private final AuditCriterion onClauseCriterion;
private final Parameters parameters;
private final List<AuditAssociationQueryImpl<?>> associationQueries = new ArrayList<>();
private final Map<String, AuditAssociationQueryImpl<AuditAssociationQueryImpl<Q>>> associationQueryMap = new HashMap<>();

public AuditAssociationQueryImpl(
final EnversService enversService,
Expand All @@ -74,7 +73,8 @@ public AuditAssociationQueryImpl(
final Map<String, String> aliasToEntityNameMap,
final Map<String, String> aliasToComponentPropertyNameMap,
final String ownerAlias,
final String userSuppliedAlias) {
final String userSuppliedAlias,
final AuditCriterion onClauseCriterion) {
this.enversService = enversService;
this.auditReader = auditReader;
this.parent = parent;
Expand Down Expand Up @@ -123,6 +123,7 @@ public AuditAssociationQueryImpl(
this.aliasToEntityNameMap = aliasToEntityNameMap;
this.aliasToComponentPropertyNameMap = aliasToComponentPropertyNameMap;
parameters = queryBuilder.addParameters( this.alias );
this.onClauseCriterion = onClauseCriterion;
}

@Override
Expand Down Expand Up @@ -156,23 +157,34 @@ public AuditAssociationQueryImpl<AuditAssociationQueryImpl<Q>> traverseRelation(
String associationName,
JoinType joinType,
String alias) {
AuditAssociationQueryImpl<AuditAssociationQueryImpl<Q>> result = associationQueryMap.get( associationName );
if ( result == null ) {
result = new AuditAssociationQueryImpl<>(
enversService,
auditReader,
this,
queryBuilder,
associationName,
joinType,
aliasToEntityNameMap,
aliasToComponentPropertyNameMap,
this.alias,
alias
);
associationQueries.add( result );
associationQueryMap.put( associationName, result );
}
return traverseRelation(
associationName,
joinType,
alias,
null
);
}

@Override
public AuditAssociationQueryImpl<AuditAssociationQueryImpl<Q>> traverseRelation(
String associationName,
JoinType joinType,
String alias,
AuditCriterion onClause) {
AuditAssociationQueryImpl<AuditAssociationQueryImpl<Q>> result = new AuditAssociationQueryImpl<>(
enversService,
auditReader,
this,
queryBuilder,
associationName,
joinType,
aliasToEntityNameMap,
aliasToComponentPropertyNameMap,
this.alias,
alias,
onClause
);
associationQueries.add( result );
return result;
}

Expand Down Expand Up @@ -283,11 +295,24 @@ public Q up() {
}

protected void addCriterionsToQuery(AuditReaderImplementor versionsReader) {
Parameters onClauseParameters;
if ( relationDescription != null ) {
createEntityJoin( enversService.getConfig() );
onClauseParameters = createEntityJoin( enversService.getConfig() );
}
else {
createComponentJoin( enversService.getConfig() );
onClauseParameters = createComponentJoin( enversService.getConfig() );
}

if ( onClauseCriterion != null ) {
onClauseCriterion.addToQuery(
enversService,
versionsReader,
aliasToEntityNameMap,
aliasToComponentPropertyNameMap,
alias,
queryBuilder,
onClauseParameters
);
}

for ( AuditCriterion criterion : criterions ) {
Expand All @@ -307,7 +332,7 @@ protected void addCriterionsToQuery(AuditReaderImplementor versionsReader) {
}
}

private void createEntityJoin(Configuration configuration) {
private Parameters createEntityJoin(Configuration configuration) {
boolean targetIsAudited = enversService.getEntitiesConfigurations().isVersioned( entityName );
String targetEntityName = entityName;
if ( targetIsAudited ) {
Expand All @@ -316,8 +341,10 @@ private void createEntityJoin(Configuration configuration) {
String originalIdPropertyName = configuration.getOriginalIdPropertyName();
String revisionPropertyPath = configuration.getRevisionNumberPath();

Parameters onClauseParameters;
if ( relationDescription.getRelationType() == RelationType.TO_ONE ) {
Parameters joinConditionParameters = queryBuilder.addJoin( joinType, targetEntityName, alias, false );
onClauseParameters = joinConditionParameters;

// owner.reference_id = target.originalId.id
IdMapper idMapperTarget;
Expand Down Expand Up @@ -350,6 +377,7 @@ else if ( relationDescription.getRelationType() == RelationType.TO_MANY_NOT_OWNI
);
}
Parameters joinConditionParameters = queryBuilder.addJoin( joinType, targetEntityName, alias, false );
onClauseParameters = joinConditionParameters;

// owner.originalId.id = target.reference_id
IdMapper idMapperOwner = enversService.getEntitiesConfigurations().get( ownerEntityName ).getIdMapper();
Expand Down Expand Up @@ -384,6 +412,7 @@ else if ( relationDescription.getRelationType() == RelationType.TO_MANY_MIDDLE

// join target_entity
Parameters joinConditionParametersTarget = queryBuilder.addJoin( joinType, targetEntityName, alias, false );
onClauseParameters = joinConditionParametersTarget;

Parameters middleParameters = queryBuilder.addParameters( middleEntityAlias );
String middleOriginalIdPropertyPath = middleEntityAlias + "." + originalIdPropertyName;
Expand Down Expand Up @@ -481,11 +510,13 @@ else if ( relationDescription.getRelationType() == RelationType.TO_MANY_MIDDLE
true
);
}
return onClauseParameters;
}

private void createComponentJoin(Configuration configuration) {
private Parameters createComponentJoin(Configuration configuration) {
String originalIdPropertyName = configuration.getOriginalIdPropertyName();
String revisionPropertyPath = configuration.getRevisionNumberPath();
Parameters onClauseParameters;
if ( componentDescription.getType() == ComponentType.MANY ) {
// join middle_entity
Parameters joinConditionParameters = queryBuilder.addJoin(
Expand All @@ -494,8 +525,10 @@ private void createComponentJoin(Configuration configuration) {
alias,
false
);
onClauseParameters = joinConditionParameters;

String middleOriginalIdPropertyPath = alias + "." + originalIdPropertyName;

// join condition: owner.reference_id = middle.id_ref_ing
String ownerPrefix = ownerAlias + "." + originalIdPropertyName;
MiddleIdData middleIdData = componentDescription.getMiddleIdData();
Expand Down Expand Up @@ -550,6 +583,7 @@ private void createComponentJoin(Configuration configuration) {
*/
String targetEntityName = configuration.getAuditEntityName( entityName );
Parameters joinConditionParameters = queryBuilder.addJoin( joinType, targetEntityName, alias, false );
onClauseParameters = joinConditionParameters;

// join condition: owner.reference_id = middle.id_reference_id
String ownerPrefix = ownerAlias + "." + originalIdPropertyName;
Expand All @@ -560,6 +594,7 @@ private void createComponentJoin(Configuration configuration) {
// join condition: owner.rev=middle.rev
joinConditionParameters.addWhere( ownerAlias, revisionPropertyPath, "=", alias, revisionPropertyPath );
}
return onClauseParameters;
}

@Override
Expand Down

0 comments on commit 3e3d227

Please sign in to comment.