Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.hibernate.envers.internal.entities.mapper.relation.query.OneAuditEntityQueryGenerator Maven / Gradle / Ivy
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or .
*/
package org.hibernate.envers.internal.entities.mapper.relation.query;
import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration;
import org.hibernate.envers.configuration.internal.GlobalConfiguration;
import org.hibernate.envers.internal.entities.mapper.id.AbstractCompositeIdMapper;
import org.hibernate.envers.internal.entities.mapper.id.IdMapper;
import org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData;
import org.hibernate.envers.internal.tools.query.Parameters;
import org.hibernate.envers.internal.tools.query.QueryBuilder;
import org.hibernate.envers.strategy.AuditStrategy;
import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.DEL_REVISION_TYPE_PARAMETER;
import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS;
import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS_DEF_AUD_STR;
import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.REVISION_PARAMETER;
/**
* Selects data from an audit entity.
*
* @author Adam Warski (adam at warski dot org)
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
* @author Chris Cranford
*/
public final class OneAuditEntityQueryGenerator extends AbstractRelationQueryGenerator {
private final String queryString;
private final String queryRemovedString;
private final String mappedBy;
private final boolean multipleIdMapperKey;
public OneAuditEntityQueryGenerator(
GlobalConfiguration globalCfg,
AuditEntitiesConfiguration verEntCfg,
AuditStrategy auditStrategy,
MiddleIdData referencingIdData,
String referencedEntityName,
MiddleIdData referencedIdData,
boolean revisionTypeInId,
String mappedBy,
boolean mappedByKey) {
super( verEntCfg, referencingIdData, revisionTypeInId );
this.mappedBy = mappedBy;
// HHH-11770 We use AbstractCompositeIdMapper here to handle EmbeddedIdMapper and MultipleIdMappper support
// so that OneAuditEntityQueryGenerator supports mappings to both @IdClass and @EmbeddedId components.
if ( ( referencedIdData.getOriginalMapper() instanceof AbstractCompositeIdMapper ) && mappedByKey ) {
multipleIdMapperKey = true;
}
else {
multipleIdMapperKey = false;
}
/*
* The valid query that we need to create:
* SELECT e FROM versionsReferencedEntity e
* WHERE
* (only entities referenced by the association; id_ref_ing = id of the referencing entity)
* e.id_ref_ing = :id_ref_ing AND
* (selecting e entities at revision :revision)
* --> for DefaultAuditStrategy:
* e.revision = (SELECT max(e2.revision) FROM versionsReferencedEntity e2
* WHERE e2.revision <= :revision AND e2.id = e.id)
*
* --> for ValidityAuditStrategy:
* e.revision <= :revision and (e.endRevision > :revision or e.endRevision is null)
*
* AND
* (only non-deleted entities)
* e.revision_type != DEL
*/
final QueryBuilder commonPart = commonQueryPart( verEntCfg.getAuditEntityName( referencedEntityName ) );
final QueryBuilder validQuery = commonPart.deepCopy();
final QueryBuilder removedQuery = commonPart.deepCopy();
createValidDataRestrictions(
globalCfg, auditStrategy, referencedIdData, validQuery, validQuery.getRootParameters()
);
createValidAndRemovedDataRestrictions( globalCfg, auditStrategy, referencedIdData, removedQuery );
queryString = queryToString( validQuery );
queryRemovedString = queryToString( removedQuery );
}
/**
* Compute common part for both queries.
*/
private QueryBuilder commonQueryPart(String versionsReferencedEntityName) {
// SELECT e FROM versionsEntity e
final QueryBuilder qb = new QueryBuilder( versionsReferencedEntityName, REFERENCED_ENTITY_ALIAS );
qb.addProjection( null, REFERENCED_ENTITY_ALIAS, null, false );
// WHERE
if ( multipleIdMapperKey ) {
// HHH-7625
// support @OneToMany(mappedBy) to @ManyToOne @IdClass attribute.
// e.originalId.id_ref_ed.id = :id_ref_ed
final IdMapper mapper = getMultipleIdPrefixedMapper();
mapper.addNamedIdEqualsToQuery( qb.getRootParameters(), null, referencingIdData.getPrefixedMapper(), true );
}
else {
// e.id_ref_ed = :id_ref_ed
referencingIdData.getPrefixedMapper().addNamedIdEqualsToQuery( qb.getRootParameters(), null, true );
}
return qb;
}
/**
* Creates query restrictions used to retrieve only actual data.
*/
private void createValidDataRestrictions(
GlobalConfiguration globalCfg, AuditStrategy auditStrategy,
MiddleIdData referencedIdData, QueryBuilder qb, Parameters rootParameters) {
final String revisionPropertyPath = verEntCfg.getRevisionNumberPath();
// (selecting e entities at revision :revision)
// --> based on auditStrategy (see above)
auditStrategy.addEntityAtRevisionRestriction(
globalCfg, qb, rootParameters, revisionPropertyPath,
verEntCfg.getRevisionEndFieldName(), true, referencedIdData, revisionPropertyPath,
verEntCfg.getOriginalIdPropName(), REFERENCED_ENTITY_ALIAS, REFERENCED_ENTITY_ALIAS_DEF_AUD_STR,
true
);
// e.revision_type != DEL
rootParameters.addWhereWithNamedParam( getRevisionTypePath(), false, "!=", DEL_REVISION_TYPE_PARAMETER );
}
/**
* Create query restrictions used to retrieve actual data and deletions that took place at exactly given revision.
*/
private void createValidAndRemovedDataRestrictions(
GlobalConfiguration globalCfg, AuditStrategy auditStrategy,
MiddleIdData referencedIdData, QueryBuilder remQb) {
final Parameters disjoint = remQb.getRootParameters().addSubParameters( "or" );
// Restrictions to match all valid rows.
final Parameters valid = disjoint.addSubParameters( "and" );
// Restrictions to match all rows deleted at exactly given revision.
final Parameters removed = disjoint.addSubParameters( "and" );
// Excluding current revision, because we need to match data valid at the previous one.
createValidDataRestrictions( globalCfg, auditStrategy, referencedIdData, remQb, valid );
// e.revision = :revision
removed.addWhereWithNamedParam( verEntCfg.getRevisionNumberPath(), false, "=", REVISION_PARAMETER );
// e.revision_type = DEL
removed.addWhereWithNamedParam( getRevisionTypePath(), false, "=", DEL_REVISION_TYPE_PARAMETER );
}
@Override
protected String getQueryString() {
return queryString;
}
@Override
protected String getQueryRemovedString() {
return queryRemovedString;
}
private IdMapper getMultipleIdPrefixedMapper() {
final String prefix = verEntCfg.getOriginalIdPropName() + "." + mappedBy + ".";
return referencingIdData.getOriginalMapper().prefixMappedProperties( prefix );
}
}