HHH-10906 - Remove the necessity of passing EnversService to AuditStrategy APIs.

This commit is contained in:
Chris Cranford 2016-06-29 13:24:33 -05:00
parent 20f68d43a4
commit fe632bc09a
5 changed files with 115 additions and 39 deletions

View File

@ -46,6 +46,7 @@ import org.jboss.logging.Logger;
* a means to share the old AuditConfiguration.
*
* @author Steve Ebersole
* @author Chris Cranford
*/
public class EnversServiceImpl implements EnversService, Configurable, Stoppable {
private static final Logger log = Logger.getLogger( EnversServiceImpl.class );
@ -137,7 +138,8 @@ public class EnversServiceImpl implements EnversService, Configurable, Stoppable
EnversServiceImpl.this.auditEntitiesConfiguration = new AuditEntitiesConfiguration(
properties,
revInfoCfgResult.getRevisionInfoEntityName()
revInfoCfgResult.getRevisionInfoEntityName(),
this
);
this.auditProcessManager = new AuditProcessManager( revInfoCfgResult.getRevisionInfoGenerator() );
this.revisionInfoQueryCreator = revInfoCfgResult.getRevisionInfoQueryCreator();

View File

@ -10,6 +10,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.hibernate.envers.boot.internal.EnversService;
import org.hibernate.envers.configuration.EnversSettings;
import org.hibernate.envers.strategy.DefaultAuditStrategy;
import org.hibernate.internal.util.config.ConfigurationHelper;
@ -19,6 +20,7 @@ import org.hibernate.internal.util.config.ConfigurationHelper;
*
* @author Adam Warski (adam at warski dot org)
* @author Stephanie Pau at Markit Group Plc
* @author Chris Cranford
*/
public class AuditEntitiesConfiguration {
private final String auditTablePrefix;
@ -44,11 +46,14 @@ public class AuditEntitiesConfiguration {
private final String revisionEndTimestampFieldName;
private final String embeddableSetOrdinalPropertyName;
private final EnversService enversService;
public AuditEntitiesConfiguration(
Properties properties,
String revisionInfoEntityName) {
String revisionInfoEntityName,
EnversService enversService) {
this.revisionInfoEntityName = revisionInfoEntityName;
this.enversService = enversService;
auditTablePrefix = ConfigurationHelper.getString( EnversSettings.AUDIT_TABLE_PREFIX, properties, "" );
auditTableSuffix = ConfigurationHelper.getString( EnversSettings.AUDIT_TABLE_SUFFIX, properties, "_AUD" );
@ -162,4 +167,13 @@ public class AuditEntitiesConfiguration {
public String getEmbeddableSetOrdinalPropertyName() {
return embeddableSetOrdinalPropertyName;
}
/**
* @deprecated (since 5.2.1), while actually added in 5.2.1, this was added to cleanup the
* audit strategy interface temporarily.
*/
@Deprecated
public EnversService getEnversService() {
return enversService;
}
}

View File

@ -10,6 +10,7 @@ import java.io.Serializable;
import org.hibernate.Session;
import org.hibernate.envers.boot.internal.EnversService;
import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration;
import org.hibernate.envers.configuration.internal.GlobalConfiguration;
import org.hibernate.envers.internal.entities.mapper.PersistentCollectionChangeData;
import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData;
@ -22,6 +23,7 @@ import org.hibernate.envers.internal.tools.query.QueryBuilder;
*
* @author Stephanie Pau
* @author Adam Warski (adam at warski dot org)
* @author Chris Cranford
*/
public interface AuditStrategy {
/**
@ -33,11 +35,40 @@ public interface AuditStrategy {
* @param id Id of the entity.
* @param data Audit data to persist
* @param revision Current revision data
* @deprecated (since 5.2.1), use {@link #perform(Session, String, AuditEntitiesConfiguration, Serializable, Object, Object)}
*/
@Deprecated
default void perform(
Session session,
String entityName,
EnversService enversService,
Serializable id,
Object data,
Object revision) {
perform(
session,
entityName,
enversService.getAuditEntitiesConfiguration(),
id,
data,
revision
);
}
/**
* Perform the persistence of audited data for regular entities.
*
* @param session Session, which can be used to persist the data.
* @param entityName Name of the entity, in which the audited change happens
* @param auditEntitiesConfiguration The audit entity configuration.
* @param id Id of the entity.
* @param data Audit data to persist.
* @param revision Current revision data.
*/
void perform(
Session session,
String entityName,
EnversService enversService,
AuditEntitiesConfiguration auditEntitiesConfiguration,
Serializable id,
Object data,
Object revision);
@ -51,15 +82,43 @@ public interface AuditStrategy {
* @param enversService The EnversService
* @param persistentCollectionChangeData Collection change data to be persisted.
* @param revision Current revision data
* @deprecated (since 5.2.1), use {@link #performCollectionChange(Session, String, String, AuditEntitiesConfiguration, PersistentCollectionChangeData, Object)}
*/
void performCollectionChange(
@Deprecated
default void performCollectionChange(
Session session,
String entityName,
String propertyName,
EnversService enversService,
PersistentCollectionChangeData persistentCollectionChangeData,
Object revision);
Object revision) {
performCollectionChange(
session,
entityName,
propertyName,
enversService.getAuditEntitiesConfiguration(),
persistentCollectionChangeData,
revision
);
}
/**
* Perform the persistence of audited data for collection ("middle") entities.
*
* @param session Session, which can be used to persist the data.
* @param entityName Name of the entity, in which the audited change happens.
* @param propertyName The name of the property holding the persistent collection
* @param auditEntitiesConfiguration audit entity configuration
* @param persistentCollectionChangeData Collection change data to be persisted.
* @param revision Current revision data
*/
void performCollectionChange(
Session session,
String entityName,
String propertyName,
AuditEntitiesConfiguration auditEntitiesConfiguration,
PersistentCollectionChangeData persistentCollectionChangeData,
Object revision);
/**
* Update the rootQueryBuilder with an extra WHERE clause to restrict the revision for a two-entity relation.

View File

@ -9,7 +9,7 @@ package org.hibernate.envers.strategy;
import java.io.Serializable;
import org.hibernate.Session;
import org.hibernate.envers.boot.internal.EnversService;
import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration;
import org.hibernate.envers.configuration.internal.GlobalConfiguration;
import org.hibernate.envers.internal.entities.mapper.PersistentCollectionChangeData;
import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData;
@ -26,6 +26,7 @@ import static org.hibernate.envers.internal.entities.mapper.relation.query.Query
*
* @author Adam Warski
* @author Stephanie Pau
* @author Chris Cranford
*/
public class DefaultAuditStrategy implements AuditStrategy {
private final SessionCacheCleaner sessionCacheCleaner;
@ -38,11 +39,11 @@ public class DefaultAuditStrategy implements AuditStrategy {
public void perform(
Session session,
String entityName,
EnversService enversService,
AuditEntitiesConfiguration auditEntitiesConfiguration,
Serializable id,
Object data,
Object revision) {
session.save( enversService.getAuditEntitiesConfiguration().getAuditEntityName( entityName ), data );
session.save( auditEntitiesConfiguration.getAuditEntityName( entityName ), data );
sessionCacheCleaner.scheduleAuditDataRemoval( session, data );
}
@ -51,7 +52,7 @@ public class DefaultAuditStrategy implements AuditStrategy {
Session session,
String entityName,
String propertyName,
EnversService enversService,
AuditEntitiesConfiguration auditEntitiesConfiguration,
PersistentCollectionChangeData persistentCollectionChangeData,
Object revision) {
session.save( persistentCollectionChangeData.getEntityName(), persistentCollectionChangeData.getData() );

View File

@ -20,7 +20,6 @@ import org.hibernate.action.spi.BeforeTransactionCompletionProcess;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.envers.RevisionType;
import org.hibernate.envers.boot.internal.EnversService;
import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration;
import org.hibernate.envers.configuration.internal.GlobalConfiguration;
import org.hibernate.envers.internal.entities.mapper.PersistentCollectionChangeData;
@ -64,6 +63,7 @@ import static org.hibernate.envers.internal.entities.mapper.relation.query.Query
* @author Stephanie Pau
* @author Adam Warski (adam at warski dot org)
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
* @author Chris Cranford
*/
public class ValidityAuditStrategy implements AuditStrategy {
/**
@ -81,13 +81,12 @@ public class ValidityAuditStrategy implements AuditStrategy {
public void perform(
final Session session,
final String entityName,
final EnversService enversService,
final AuditEntitiesConfiguration audEntitiesCfg,
final Serializable id,
final Object data,
final Object revision) {
final AuditEntitiesConfiguration audEntitiesCfg = enversService.getAuditEntitiesConfiguration();
final String auditedEntityName = audEntitiesCfg.getAuditEntityName( entityName );
final String revisionInfoEntityName = enversService.getAuditEntitiesConfiguration().getRevisionInfoEntityName();
final String revisionInfoEntityName = audEntitiesCfg.getRevisionInfoEntityName();
// Save the audit data
session.save( auditedEntityName, data );
@ -99,8 +98,8 @@ public class ValidityAuditStrategy implements AuditStrategy {
// inserted for the first time. But in case a deleted primary key value was
// reused, this guarantees correct strategy behavior: exactly one row with
// null end date exists for each identifier.
final boolean reuseEntityIdentifier = enversService.getGlobalConfiguration().isAllowIdentifierReuse();
if ( reuseEntityIdentifier || getRevisionType( enversService, data ) != RevisionType.ADD ) {
final boolean reuseEntityIdentifier = audEntitiesCfg.getEnversService().getGlobalConfiguration().isAllowIdentifierReuse();
if ( reuseEntityIdentifier || getRevisionType( audEntitiesCfg, data ) != RevisionType.ADD ) {
// Register transaction completion process to guarantee execution of UPDATE statement afterQuery INSERT.
( (EventSource) session ).getActionQueue().registerProcess( new BeforeTransactionCompletionProcess() {
@Override
@ -129,9 +128,9 @@ public class ValidityAuditStrategy implements AuditStrategy {
}
final Type revisionInfoIdType = sessionImplementor.getFactory().getMetamodel().entityPersister( revisionInfoEntityName ).getIdentifierType();
final String revEndColumnName = rootAuditedEntityQueryable.toColumns( enversService.getAuditEntitiesConfiguration().getRevisionEndFieldName() )[0];
final String revEndColumnName = rootAuditedEntityQueryable.toColumns( audEntitiesCfg.getRevisionEndFieldName() )[0];
final boolean isRevisionEndTimestampEnabled = enversService.getAuditEntitiesConfiguration().isRevisionEndTimestampEnabled();
final boolean isRevisionEndTimestampEnabled = audEntitiesCfg.isRevisionEndTimestampEnabled();
// update audit_ent set REVEND = ? [, REVEND_TSTMP = ?] where (prod_ent_id) = ? and REV <> ? and REVEND is null
final Update update = new Update( sessionImplementor.getFactory().getJdbcServices().getDialect() ).setTableName( updateTableName );
@ -140,7 +139,7 @@ public class ValidityAuditStrategy implements AuditStrategy {
// set [, REVEND_TSTMP = ?]
if ( isRevisionEndTimestampEnabled ) {
update.addColumn(
rootAuditedEntityQueryable.toColumns( enversService.getAuditEntitiesConfiguration().getRevisionEndTimestampFieldName() )[0]
rootAuditedEntityQueryable.toColumns( audEntitiesCfg.getRevisionEndTimestampFieldName() )[0]
);
}
@ -148,7 +147,7 @@ public class ValidityAuditStrategy implements AuditStrategy {
update.addPrimaryKeyColumns( rootProductionEntityQueryable.getIdentifierColumnNames() );
// where REV <> ?
update.addWhereColumn(
rootAuditedEntityQueryable.toColumns( enversService.getAuditEntitiesConfiguration().getRevisionNumberPath() )[0], "<> ?"
rootAuditedEntityQueryable.toColumns( audEntitiesCfg.getRevisionNumberPath() )[0], "<> ?"
);
// where REVEND is null
update.addWhereColumn( revEndColumnName, " is null" );
@ -167,9 +166,10 @@ public class ValidityAuditStrategy implements AuditStrategy {
int index = 1;
// set REVEND = ?
final Number revisionNumber = enversService.getRevisionInfoNumberReader().getRevisionNumber(
revision
);
final Number revisionNumber = audEntitiesCfg.getEnversService()
.getRevisionInfoNumberReader()
.getRevisionNumber( revision );
revisionInfoIdType.nullSafeSet(
preparedStatement, revisionNumber, index, sessionImplementor
);
@ -180,7 +180,7 @@ public class ValidityAuditStrategy implements AuditStrategy {
final Object revEndTimestampObj = revisionTimestampGetter.get( revision );
final Date revisionEndTimestamp = convertRevEndTimestampToDate( revEndTimestampObj );
final Type revEndTsType = rootAuditedEntityQueryable.getPropertyType(
enversService.getAuditEntitiesConfiguration().getRevisionEndTimestampFieldName()
audEntitiesCfg.getRevisionEndTimestampFieldName()
);
revEndTsType.nullSafeSet(
preparedStatement, revisionEndTimestamp, index, sessionImplementor
@ -195,7 +195,7 @@ public class ValidityAuditStrategy implements AuditStrategy {
// where REV <> ?
final Type revType = rootAuditedEntityQueryable.getPropertyType(
enversService.getAuditEntitiesConfiguration().getRevisionNumberPath()
audEntitiesCfg.getRevisionNumberPath()
);
revType.nullSafeSet( preparedStatement, revisionNumber, index, sessionImplementor );
@ -215,7 +215,7 @@ public class ValidityAuditStrategy implements AuditStrategy {
}
);
if ( rowCount != 1 && ( !reuseEntityIdentifier || ( getRevisionType( enversService, data ) != RevisionType.ADD ) ) ) {
if ( rowCount != 1 && ( !reuseEntityIdentifier || ( getRevisionType( audEntitiesCfg, data ) != RevisionType.ADD ) ) ) {
throw new RuntimeException(
"Cannot update previous revision for entity " + auditedEntityName + " and id " + id
);
@ -236,16 +236,16 @@ public class ValidityAuditStrategy implements AuditStrategy {
Session session,
String entityName,
String propertyName,
EnversService enversService,
AuditEntitiesConfiguration auditEntitiesConfiguration,
PersistentCollectionChangeData persistentCollectionChangeData, Object revision) {
final QueryBuilder qb = new QueryBuilder( persistentCollectionChangeData.getEntityName(), MIDDLE_ENTITY_ALIAS );
final String originalIdPropName = enversService.getAuditEntitiesConfiguration().getOriginalIdPropName();
final String originalIdPropName = auditEntitiesConfiguration.getOriginalIdPropName();
final Map<String, Object> originalId = (Map<String, Object>) persistentCollectionChangeData.getData().get(
originalIdPropName
);
final String revisionFieldName = enversService.getAuditEntitiesConfiguration().getRevisionFieldName();
final String revisionTypePropName = enversService.getAuditEntitiesConfiguration().getRevisionTypePropName();
final String revisionFieldName = auditEntitiesConfiguration.getRevisionFieldName();
final String revisionTypePropName = auditEntitiesConfiguration.getRevisionTypePropName();
// Adding a parameter for each id component, except the rev number and type.
for ( Map.Entry<String, Object> originalIdEntry : originalId.entrySet() ) {
@ -272,7 +272,7 @@ public class ValidityAuditStrategy implements AuditStrategy {
}
}
addEndRevisionNullRestriction( enversService, qb.getRootParameters() );
addEndRevisionNullRestriction( auditEntitiesConfiguration, qb.getRootParameters() );
final List<Object> l = qb.toQuery( session ).setLockOptions( LockOptions.UPGRADE ).list();
@ -281,7 +281,7 @@ public class ValidityAuditStrategy implements AuditStrategy {
// ADD, we may need to update the last revision.
if ( l.size() > 0 ) {
updateLastRevision(
session, enversService, l, originalId, persistentCollectionChangeData.getEntityName(), revision
session, auditEntitiesConfiguration, l, originalId, persistentCollectionChangeData.getEntityName(), revision
);
}
@ -290,8 +290,8 @@ public class ValidityAuditStrategy implements AuditStrategy {
sessionCacheCleaner.scheduleAuditDataRemoval( session, persistentCollectionChangeData.getData() );
}
private void addEndRevisionNullRestriction(EnversService enversService, Parameters rootParameters) {
rootParameters.addWhere( enversService.getAuditEntitiesConfiguration().getRevisionEndFieldName(), true, "is", "null", false );
private void addEndRevisionNullRestriction(AuditEntitiesConfiguration auditEntitiesConfiguration, Parameters rootParameters) {
rootParameters.addWhere( auditEntitiesConfiguration.getRevisionEndFieldName(), true, "is", "null", false );
}
public void addEntityAtRevisionRestriction(
@ -327,14 +327,14 @@ public class ValidityAuditStrategy implements AuditStrategy {
}
@SuppressWarnings({"unchecked"})
private RevisionType getRevisionType(EnversService enversService, Object data) {
return (RevisionType) ( (Map<String, Object>) data ).get( enversService.getAuditEntitiesConfiguration().getRevisionTypePropName() );
private RevisionType getRevisionType(AuditEntitiesConfiguration auditEntitiesConfiguration, Object data) {
return (RevisionType) ( (Map<String, Object>) data ).get( auditEntitiesConfiguration.getRevisionTypePropName() );
}
@SuppressWarnings({"unchecked"})
private void updateLastRevision(
Session session,
EnversService enversService,
AuditEntitiesConfiguration auditEntitiesConfiguration,
List<Object> l,
Object id,
String auditedEntityName,
@ -343,12 +343,12 @@ public class ValidityAuditStrategy implements AuditStrategy {
if ( l.size() == 1 ) {
// Setting the end revision to be the current rev
Object previousData = l.get( 0 );
String revisionEndFieldName = enversService.getAuditEntitiesConfiguration().getRevisionEndFieldName();
String revisionEndFieldName = auditEntitiesConfiguration.getRevisionEndFieldName();
( (Map<String, Object>) previousData ).put( revisionEndFieldName, revision );
if ( enversService.getAuditEntitiesConfiguration().isRevisionEndTimestampEnabled() ) {
if ( auditEntitiesConfiguration.isRevisionEndTimestampEnabled() ) {
// Determine the value of the revision property annotated with @RevisionTimestamp
String revEndTimestampFieldName = enversService.getAuditEntitiesConfiguration().getRevisionEndTimestampFieldName();
String revEndTimestampFieldName = auditEntitiesConfiguration.getRevisionEndTimestampFieldName();
Object revEndTimestampObj = this.revisionTimestampGetter.get( revision );
Date revisionEndTimestamp = convertRevEndTimestampToDate( revEndTimestampObj );