HHH-5560 - Rename Envers ValidAuditTimeStrategy to ValidityAuditTimeStrategy

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@20717 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Erik-Berndt Scheper 2010-09-26 19:55:50 +00:00
parent 5823732c45
commit dd8fe46f58
13 changed files with 204 additions and 157 deletions

View File

@ -35,7 +35,7 @@ import java.util.Properties;
import org.hibernate.MappingException;
import org.hibernate.envers.strategy.DefaultAuditStrategy;
import org.hibernate.envers.strategy.ValidTimeAuditStrategy;
import org.hibernate.envers.strategy.ValidityAuditStrategy;
/**
* Configuration of versions entities - names of fields, entities and tables created to store versioning information.
@ -93,7 +93,7 @@ public class AuditEntitiesConfiguration {
revisionTypePropType = "byte";
revisionEndFieldName = getProperty(properties,
"org.hibernate.envers.audit_strategy_valid_time_end_name",
"org.hibernate.envers.audit_strategy_validity_end_rev_field_name",
"org.hibernate.envers.audit_strategy_valid_time_end_name",
"REVEND");

View File

@ -28,9 +28,11 @@ import java.util.Iterator;
import java.util.Map;
import org.dom4j.Element;
import org.hibernate.envers.configuration.AuditConfiguration;
import org.hibernate.envers.configuration.GlobalConfiguration;
import org.hibernate.MappingException;
import org.hibernate.cfg.Configuration;
import org.hibernate.envers.RelationTargetAuditMode;
import org.hibernate.envers.configuration.AuditEntitiesConfiguration;
import org.hibernate.envers.configuration.GlobalConfiguration;
import org.hibernate.envers.configuration.metadata.reader.ClassAuditingData;
import org.hibernate.envers.configuration.metadata.reader.PropertyAuditingData;
import org.hibernate.envers.entities.EntityConfiguration;
@ -40,15 +42,20 @@ import org.hibernate.envers.entities.mapper.ExtendedPropertyMapper;
import org.hibernate.envers.entities.mapper.MultiPropertyMapper;
import org.hibernate.envers.entities.mapper.SubclassPropertyMapper;
import org.hibernate.envers.strategy.AuditStrategy;
import org.hibernate.envers.strategy.ValidTimeAuditStrategy;
import org.hibernate.envers.strategy.ValidityAuditStrategy;
import org.hibernate.envers.tools.StringTools;
import org.hibernate.envers.tools.Triple;
import org.hibernate.envers.RelationTargetAuditMode;
import org.hibernate.MappingException;
import org.hibernate.cfg.Configuration;
import org.hibernate.mapping.*;
import org.hibernate.type.*;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Join;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.Value;
import org.hibernate.type.CollectionType;
import org.hibernate.type.ComponentType;
import org.hibernate.type.ManyToOneType;
import org.hibernate.type.OneToOneType;
import org.hibernate.type.Type;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -139,7 +146,7 @@ public final class AuditMetadataGenerator {
private void addEndRevision(Element any_mapping) {
// Add the end-revision field, if the appropriate strategy is used.
if (ValidTimeAuditStrategy.class.getName().equals(verEntCfg.getAuditStrategyName())) {
if (auditStrategy instanceof ValidityAuditStrategy) {
Element end_rev_mapping = (Element) revisionInfoRelationMapping.clone();
end_rev_mapping.setName("many-to-one");
end_rev_mapping.addAttribute("name", verEntCfg.getRevisionEndFieldName());

View File

@ -61,7 +61,7 @@ public final class OneAuditEntityQueryGenerator implements RelationQueryGenerato
* e.revision = (SELECT max(e2.revision) FROM versionsReferencedEntity e2
* WHERE e2.revision <= :revision AND e2.id = e.id)
*
* --> for ValidTimeAuditStrategy:
* --> for ValidityAuditStrategy:
* e.revision <= :revision and (e.endRevision > :revision or e.endRevision is null)
*
* AND

View File

@ -62,7 +62,7 @@ public final class OneEntityQueryGenerator implements RelationQueryGenerator {
* ee.revision = (SELECT max(ee2.revision) FROM middleEntity ee2
* WHERE ee2.revision <= :revision AND ee2.originalId.* = ee.originalId.*)
*
* --> for ValidTimeAuditStrategy:
* --> for ValidityAuditStrategy:
* ee.revision <= :revision and (ee.endRevision > :revision or ee.endRevision is null)
*
* AND

View File

@ -70,7 +70,7 @@ public final class ThreeEntityQueryGenerator implements RelationQueryGenerator {
* e.revision = (SELECT max(e2.revision) FROM versionsReferencedEntity e2
* WHERE e2.revision <= :revision AND e2.id = e.id)
*
* --> for ValidTimeAuditStrategy:
* --> for ValidityAuditStrategy:
* e.revision <= :revision and (e.endRevision > :revision or e.endRevision is null)
*
* AND
@ -80,7 +80,7 @@ public final class ThreeEntityQueryGenerator implements RelationQueryGenerator {
* f.revision = (SELECT max(f2.revision) FROM versionsIndexEntity f2
* WHERE f2.revision <= :revision AND f2.id_ref_ed = f.id_ref_ed)
*
* --> for ValidTimeAuditStrategy:
* --> for ValidityAuditStrategy:
* f.revision <= :revision and (f.endRevision > :revision or f.endRevision is null)
*
* AND
@ -90,7 +90,7 @@ public final class ThreeEntityQueryGenerator implements RelationQueryGenerator {
* ee.revision = (SELECT max(ee2.revision) FROM middleEntity ee2
* WHERE ee2.revision <= :revision AND ee2.originalId.* = ee.originalId.*)
*
* --> for ValidTimeAuditStrategy:
* --> for ValidityAuditStrategy:
* ee.revision <= :revision and (ee.endRevision > :revision or ee.endRevision is null)
*
and (

View File

@ -68,7 +68,7 @@ public final class TwoEntityOneAuditedQueryGenerator implements RelationQueryGen
* ee.revision = (SELECT max(ee2.revision) FROM middleEntity ee2
* WHERE ee2.revision <= :revision AND ee2.originalId.* = ee.originalId.*)
*
* --> for ValidTimeAuditStrategy:
* --> for ValidityAuditStrategy:
* ee.revision <= :revision and (ee.endRevision > :revision or ee.endRevision is null)
*
* AND

View File

@ -68,7 +68,7 @@ public final class TwoEntityQueryGenerator implements RelationQueryGenerator {
* e.revision = (SELECT max(e2.revision) FROM versionsReferencedEntity e2
* WHERE e2.revision <= :revision AND e2.id = e.id)
*
* --> for ValidTimeAuditStrategy:
* --> for ValidityAuditStrategy:
* e.revision <= :revision and (e.endRevision > :revision or e.endRevision is null)
*
* AND
@ -78,7 +78,7 @@ public final class TwoEntityQueryGenerator implements RelationQueryGenerator {
* ee.revision = (SELECT max(ee2.revision) FROM middleEntity ee2
* WHERE ee2.revision <= :revision AND ee2.originalId.* = ee.originalId.*)
*
* --> for ValidTimeAuditStrategy:
* --> for ValidityAuditStrategy:
* ee.revision <= :revision and (ee.endRevision > :revision or ee.endRevision is null)
*
* (only non-deleted entities and associations)

View File

@ -67,7 +67,7 @@ public class EntitiesAtRevisionQuery extends AbstractAuditQuery {
* e.revision = (SELECT max(e2.revision) FROM versionsReferencedEntity e2
* WHERE e2.revision <= :revision AND e2.id = e.id)
*
* --> for ValidTimeAuditStrategy:
* --> for ValidityAuditStrategy:
* e.revision <= :revision and (e.endRevision > :revision or e.endRevision is null)
*
* AND

View File

@ -49,7 +49,7 @@ public interface AuditStrategy {
* <li>For {@link DefaultAuditStrategy} a subquery is created:
* <p><code>e.revision = (SELECT max(...) ...)</code></p>
* </li>
* <li>for {@link ValidTimeAuditStrategy} the revision-end column is used:
* <li>for {@link ValidityAuditStrategy} the revision-end column is used:
* <p><code>e.revision <= :revision and (e.endRevision > :revision or e.endRevision is null)</code></p>
* </li>
* </ul>
@ -57,13 +57,13 @@ public interface AuditStrategy {
* @param globalCfg the {@link GlobalConfiguration}
* @param rootQueryBuilder the {@link QueryBuilder} that will be updated
* @param revisionProperty property of the revision column
* @param revisionEndProperty property of the revisionEnd column (only used for {@link ValidTimeAuditStrategy})
* @param revisionEndProperty property of the revisionEnd column (only used for {@link ValidityAuditStrategy})
* @param addAlias {@code boolean} indicator if a left alias is needed
* @param idData id-information for the two-entity relation (only used for {@link DefaultAuditStrategy})
* @param revisionPropertyPath path of the revision property (only used for {@link ValidTimeAuditStrategy})
* @param originalIdPropertyName name of the id property (only used for {@link ValidTimeAuditStrategy})
* @param alias1 an alias used for subquery (only used for {@link ValidTimeAuditStrategy})
* @param alias2 an alias used for subquery (only used for {@link ValidTimeAuditStrategy})
* @param revisionPropertyPath path of the revision property (only used for {@link ValidityAuditStrategy})
* @param originalIdPropertyName name of the id property (only used for {@link ValidityAuditStrategy})
* @param alias1 an alias used for subquery (only used for {@link ValidityAuditStrategy})
* @param alias2 an alias used for subquery (only used for {@link ValidityAuditStrategy})
*/
void addEntityAtRevisionRestriction(GlobalConfiguration globalCfg, QueryBuilder rootQueryBuilder,
String revisionProperty, String revisionEndProperty, boolean addAlias, MiddleIdData idData,
@ -76,20 +76,20 @@ public interface AuditStrategy {
* <li>For {@link DefaultAuditStrategy} a subquery is created:
* <p><code>e.revision = (SELECT max(...) ...)</code></p>
* </li>
* <li>for {@link ValidTimeAuditStrategy} the revision-end column is used:
* <li>for {@link ValidityAuditStrategy} the revision-end column is used:
* <p><code>e.revision <= :revision and (e.endRevision > :revision or e.endRevision is null)</code></p>
* </li>
* </ul>
*
* @param rootQueryBuilder the {@link QueryBuilder} that will be updated
* @param revisionProperty property of the revision column
* @param revisionEndProperty property of the revisionEnd column (only used for {@link ValidTimeAuditStrategy})
* @param revisionEndProperty property of the revisionEnd column (only used for {@link ValidityAuditStrategy})
* @param addAlias {@code boolean} indicator if a left alias is needed
* @param referencingIdData id-information for the middle-entity association (only used for {@link DefaultAuditStrategy})
* @param versionsMiddleEntityName name of the middle-entity
* @param eeOriginalIdPropertyPath name of the id property (only used for {@link ValidTimeAuditStrategy})
* @param revisionPropertyPath path of the revision property (only used for {@link ValidTimeAuditStrategy})
* @param originalIdPropertyName name of the id property (only used for {@link ValidTimeAuditStrategy})
* @param eeOriginalIdPropertyPath name of the id property (only used for {@link ValidityAuditStrategy})
* @param revisionPropertyPath path of the revision property (only used for {@link ValidityAuditStrategy})
* @param originalIdPropertyName name of the id property (only used for {@link ValidityAuditStrategy})
* @param componentDatas information about the middle-entity relation
*/
void addAssociationAtRevisionRestriction(QueryBuilder rootQueryBuilder, String revisionProperty,

View File

@ -1,135 +1,25 @@
package org.hibernate.envers.strategy;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.hibernate.Session;
import org.hibernate.envers.RevisionType;
import org.hibernate.envers.configuration.AuditConfiguration;
import org.hibernate.envers.configuration.AuditEntitiesConfiguration;
import org.hibernate.envers.configuration.GlobalConfiguration;
import org.hibernate.envers.entities.mapper.PersistentCollectionChangeData;
import org.hibernate.envers.entities.mapper.id.IdMapper;
import org.hibernate.envers.entities.mapper.relation.MiddleComponentData;
import org.hibernate.envers.entities.mapper.relation.MiddleIdData;
import org.hibernate.envers.tools.query.Parameters;
import org.hibernate.envers.tools.query.QueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Audit strategy which additionally manages the end-revision number: updates the end-revision field on the last
* revision that was persisted before the current one.
* Deprecated Audit strategy class.
*
* @author Stephanie Pau
* @author Adam Warski (adam at warski dot org)
*
* @deprecated use {@link ValidityAuditStrategy} instead.
*/
public class ValidTimeAuditStrategy implements AuditStrategy {
public void perform(Session session, String entityName, AuditConfiguration auditCfg, Serializable id, Object data,
Object revision) {
AuditEntitiesConfiguration audEntCfg = auditCfg.getAuditEntCfg();
String auditedEntityName = audEntCfg.getAuditEntityName(entityName);
public class ValidTimeAuditStrategy extends ValidityAuditStrategy {
// Update the end date of the previous row if this operation is expected to have a previous row
if (getRevisionType(auditCfg, data) != RevisionType.ADD) {
/*
Constructing a query:
select e from audited_ent e where e.end_rev is null and e.id = :id
*/
private final Logger log = LoggerFactory.getLogger(ValidTimeAuditStrategy.class);
QueryBuilder qb = new QueryBuilder(auditedEntityName, "e");
// e.id = :id
IdMapper idMapper = auditCfg.getEntCfg().get(entityName).getIdMapper();
idMapper.addIdEqualsToQuery(qb.getRootParameters(), id, auditCfg.getAuditEntCfg().getOriginalIdPropName(), true);
updateLastRevision(session, auditCfg, qb, id, auditedEntityName, revision);
}
// Save the audit data
session.save(auditedEntityName, data);
}
@SuppressWarnings({"unchecked"})
public void performCollectionChange(Session session, AuditConfiguration auditCfg,
PersistentCollectionChangeData persistentCollectionChangeData, Object revision) {
// Update the end date of the previous row if this operation is expected to have a previous row
if (getRevisionType(auditCfg, persistentCollectionChangeData.getData()) != RevisionType.ADD) {
/*
Constructing a query (there are multiple id fields):
select e from audited_middle_ent e where e.end_rev is null and e.id1 = :id1 and e.id2 = :id2 ...
*/
QueryBuilder qb = new QueryBuilder(persistentCollectionChangeData.getEntityName(), "e");
// Adding a parameter for each id component, except the rev number
String originalIdPropName = auditCfg.getAuditEntCfg().getOriginalIdPropName();
Map<String, Object> originalId = (Map<String, Object>) persistentCollectionChangeData.getData().get(
originalIdPropName);
for (Map.Entry<String, Object> originalIdEntry : originalId.entrySet()) {
if (!auditCfg.getAuditEntCfg().getRevisionFieldName().equals(originalIdEntry.getKey())) {
qb.getRootParameters().addWhereWithParam(originalIdPropName + "." + originalIdEntry.getKey(),
true, "=", originalIdEntry.getValue());
}
}
updateLastRevision(session, auditCfg, qb, originalId, persistentCollectionChangeData.getEntityName(), revision);
}
// Save the audit data
session.save(persistentCollectionChangeData.getEntityName(), persistentCollectionChangeData.getData());
}
public void addEntityAtRevisionRestriction(GlobalConfiguration globalCfg, QueryBuilder rootQueryBuilder,
String revisionProperty,String revisionEndProperty, boolean addAlias,
MiddleIdData idData, String revisionPropertyPath, String originalIdPropertyName,
String alias1, String alias2) {
Parameters rootParameters = rootQueryBuilder.getRootParameters();
addRevisionRestriction(rootParameters, revisionProperty, revisionEndProperty, addAlias);
}
public void addAssociationAtRevisionRestriction(QueryBuilder rootQueryBuilder, String revisionProperty,
String revisionEndProperty, boolean addAlias, MiddleIdData referencingIdData,
String versionsMiddleEntityName, String eeOriginalIdPropertyPath, String revisionPropertyPath,
String originalIdPropertyName, MiddleComponentData... componentDatas) {
Parameters rootParameters = rootQueryBuilder.getRootParameters();
addRevisionRestriction(rootParameters, revisionProperty, revisionEndProperty, addAlias);
}
private void addRevisionRestriction(Parameters rootParameters,
String revisionProperty, String revisionEndProperty, boolean addAlias) {
// e.revision <= _revision and (e.endRevision > _revision or e.endRevision is null)
Parameters subParm = rootParameters.addSubParameters("or");
rootParameters.addWhereWithNamedParam(revisionProperty, addAlias, "<=", "revision");
subParm.addWhereWithNamedParam(revisionEndProperty + ".id", addAlias, ">", "revision");
subParm.addWhere(revisionEndProperty, addAlias, "is", "null", false);
/**
* Default constructor. Log a warn message that this class is deprecated.
*/
public ValidTimeAuditStrategy() {
log.warn("ValidTimeAuditStrategy is deprecated, please use ValidityAuditStrategy instead");
}
@SuppressWarnings({"unchecked"})
private RevisionType getRevisionType(AuditConfiguration auditCfg, Object data) {
return (RevisionType) ((Map<String, Object>) data).get(auditCfg.getAuditEntCfg().getRevisionTypePropName());
}
@SuppressWarnings({"unchecked"})
private void updateLastRevision(Session session, AuditConfiguration auditCfg, QueryBuilder qb,
Object id, String auditedEntityName, Object revision) {
String revisionEndFieldName = auditCfg.getAuditEntCfg().getRevisionEndFieldName();
// e.end_rev is null
qb.getRootParameters().addWhere(revisionEndFieldName, true, "is", "null", false);
List l = qb.toQuery(session).list();
// There should be one entry
if (l.size() == 1) {
// Setting the end revision to be the current rev
Object previousData = l.get(0);
((Map<String, Object>) previousData).put(revisionEndFieldName, revision);
// Saving the previous version
session.save(auditedEntityName, previousData);
} else {
throw new RuntimeException("Cannot find previous revision for entity " + auditedEntityName + " and id " + id);
}
}
}

View File

@ -0,0 +1,150 @@
package org.hibernate.envers.strategy;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.hibernate.Session;
import org.hibernate.envers.RevisionType;
import org.hibernate.envers.configuration.AuditConfiguration;
import org.hibernate.envers.configuration.AuditEntitiesConfiguration;
import org.hibernate.envers.configuration.GlobalConfiguration;
import org.hibernate.envers.entities.mapper.PersistentCollectionChangeData;
import org.hibernate.envers.entities.mapper.id.IdMapper;
import org.hibernate.envers.entities.mapper.relation.MiddleComponentData;
import org.hibernate.envers.entities.mapper.relation.MiddleIdData;
import org.hibernate.envers.tools.query.Parameters;
import org.hibernate.envers.tools.query.QueryBuilder;
/**
* Audit strategy which persists and retrieves audit information using a validity algorithm, based on the
* start-revision and end-revision of a row in the audit tables.
* <p>This algorithm works as follows:
* <ul>
* <li>For a <strong>new row</strong> that is persisted in an audit table, only the <strong>start-revision</strong> column of that row is set</li>
* <li>At the same time the <strong>end-revision</strong> field of the <strong>previous</strong> audit row is set to this revision</li>
* <li>Queries are retrieved using 'between start and end revision', instead of a subquery.</li>
* </ul>
* </p>
*
* <p>
* This has a few important consequences that need to be judged against against each other:
* <ul>
* <li>Persisting audit information is a bit slower, because an extra row is updated</li>
* <li>Retrieving audit information is a lot faster</li>
* </ul>
* </p>
*
* @author Stephanie Pau
* @author Adam Warski (adam at warski dot org)
*/
public class ValidityAuditStrategy implements AuditStrategy {
public void perform(Session session, String entityName, AuditConfiguration auditCfg, Serializable id, Object data,
Object revision) {
AuditEntitiesConfiguration audEntCfg = auditCfg.getAuditEntCfg();
String auditedEntityName = audEntCfg.getAuditEntityName(entityName);
// Update the end date of the previous row if this operation is expected to have a previous row
if (getRevisionType(auditCfg, data) != RevisionType.ADD) {
/*
Constructing a query:
select e from audited_ent e where e.end_rev is null and e.id = :id
*/
QueryBuilder qb = new QueryBuilder(auditedEntityName, "e");
// e.id = :id
IdMapper idMapper = auditCfg.getEntCfg().get(entityName).getIdMapper();
idMapper.addIdEqualsToQuery(qb.getRootParameters(), id, auditCfg.getAuditEntCfg().getOriginalIdPropName(), true);
updateLastRevision(session, auditCfg, qb, id, auditedEntityName, revision);
}
// Save the audit data
session.save(auditedEntityName, data);
}
@SuppressWarnings({"unchecked"})
public void performCollectionChange(Session session, AuditConfiguration auditCfg,
PersistentCollectionChangeData persistentCollectionChangeData, Object revision) {
// Update the end date of the previous row if this operation is expected to have a previous row
if (getRevisionType(auditCfg, persistentCollectionChangeData.getData()) != RevisionType.ADD) {
/*
Constructing a query (there are multiple id fields):
select e from audited_middle_ent e where e.end_rev is null and e.id1 = :id1 and e.id2 = :id2 ...
*/
QueryBuilder qb = new QueryBuilder(persistentCollectionChangeData.getEntityName(), "e");
// Adding a parameter for each id component, except the rev number
String originalIdPropName = auditCfg.getAuditEntCfg().getOriginalIdPropName();
Map<String, Object> originalId = (Map<String, Object>) persistentCollectionChangeData.getData().get(
originalIdPropName);
for (Map.Entry<String, Object> originalIdEntry : originalId.entrySet()) {
if (!auditCfg.getAuditEntCfg().getRevisionFieldName().equals(originalIdEntry.getKey())) {
qb.getRootParameters().addWhereWithParam(originalIdPropName + "." + originalIdEntry.getKey(),
true, "=", originalIdEntry.getValue());
}
}
updateLastRevision(session, auditCfg, qb, originalId, persistentCollectionChangeData.getEntityName(), revision);
}
// Save the audit data
session.save(persistentCollectionChangeData.getEntityName(), persistentCollectionChangeData.getData());
}
public void addEntityAtRevisionRestriction(GlobalConfiguration globalCfg, QueryBuilder rootQueryBuilder,
String revisionProperty,String revisionEndProperty, boolean addAlias,
MiddleIdData idData, String revisionPropertyPath, String originalIdPropertyName,
String alias1, String alias2) {
Parameters rootParameters = rootQueryBuilder.getRootParameters();
addRevisionRestriction(rootParameters, revisionProperty, revisionEndProperty, addAlias);
}
public void addAssociationAtRevisionRestriction(QueryBuilder rootQueryBuilder, String revisionProperty,
String revisionEndProperty, boolean addAlias, MiddleIdData referencingIdData,
String versionsMiddleEntityName, String eeOriginalIdPropertyPath, String revisionPropertyPath,
String originalIdPropertyName, MiddleComponentData... componentDatas) {
Parameters rootParameters = rootQueryBuilder.getRootParameters();
addRevisionRestriction(rootParameters, revisionProperty, revisionEndProperty, addAlias);
}
private void addRevisionRestriction(Parameters rootParameters,
String revisionProperty, String revisionEndProperty, boolean addAlias) {
// e.revision <= _revision and (e.endRevision > _revision or e.endRevision is null)
Parameters subParm = rootParameters.addSubParameters("or");
rootParameters.addWhereWithNamedParam(revisionProperty, addAlias, "<=", "revision");
subParm.addWhereWithNamedParam(revisionEndProperty + ".id", addAlias, ">", "revision");
subParm.addWhere(revisionEndProperty, addAlias, "is", "null", false);
}
@SuppressWarnings({"unchecked"})
private RevisionType getRevisionType(AuditConfiguration auditCfg, Object data) {
return (RevisionType) ((Map<String, Object>) data).get(auditCfg.getAuditEntCfg().getRevisionTypePropName());
}
@SuppressWarnings({"unchecked"})
private void updateLastRevision(Session session, AuditConfiguration auditCfg, QueryBuilder qb,
Object id, String auditedEntityName, Object revision) {
String revisionEndFieldName = auditCfg.getAuditEntCfg().getRevisionEndFieldName();
// e.end_rev is null
qb.getRootParameters().addWhere(revisionEndFieldName, true, "is", "null", false);
List<Object> l = qb.toQuery(session).list();
// There should be one entry
if (l.size() == 1) {
// Setting the end revision to be the current rev
Object previousData = l.get(0);
((Map<String, Object>) previousData).put(revisionEndFieldName, revision);
// Saving the previous version
session.save(auditedEntityName, previousData);
} else {
throw new RuntimeException("Cannot find previous revision for entity " + auditedEntityName + " and id " + id);
}
}
}

View File

@ -23,7 +23,7 @@
<!--<property name="connection.username">root</property>-->
<!--<property name="connection.password"></property>-->
<!--<property name="org.hibernate.envers.audit_strategy">org.hibernate.envers.strategy.ValidTimeAuditStrategy</property>-->
<!--<property name="org.hibernate.envers.audit_strategy">org.hibernate.envers.strategy.ValidityAuditStrategy</property>-->
<!--<property name="hibernate.jdbc.batch_size">100</property>-->

View File

@ -84,8 +84,8 @@
&packages;
</packages>
</test>
<test name="ValidTimeAuditStrategy">
<parameter name="auditStrategy" value="org.hibernate.envers.strategy.ValidTimeAuditStrategy" />
<test name="ValidityAuditStrategy">
<parameter name="auditStrategy" value="org.hibernate.envers.strategy.ValidityAuditStrategy" />
<packages>
&packages;
</packages>