Author: fbascheper
Date: 2010-09-26 15:55:50 -0400 (Sun, 26 Sep 2010)
New Revision: 20717
Added:
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/ValidityAuditStrategy.java
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/configuration/AuditEntitiesConfiguration.java
core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/OneAuditEntityQueryGenerator.java
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/OneEntityQueryGenerator.java
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/ThreeEntityQueryGenerator.java
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/TwoEntityOneAuditedQueryGenerator.java
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/TwoEntityQueryGenerator.java
core/trunk/envers/src/main/java/org/hibernate/envers/query/impl/EntitiesAtRevisionQuery.java
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/AuditStrategy.java
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/ValidTimeAuditStrategy.java
core/trunk/envers/src/test/resources/hibernate.test.cfg.xml
core/trunk/envers/src/test/resources/testng.xml
Log:
HHH-5560 - Rename Envers ValidAuditTimeStrategy to ValidityAuditTimeStrategy
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/configuration/AuditEntitiesConfiguration.java
===================================================================
---
core/trunk/envers/src/main/java/org/hibernate/envers/configuration/AuditEntitiesConfiguration.java 2010-09-26
19:12:41 UTC (rev 20716)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/configuration/AuditEntitiesConfiguration.java 2010-09-26
19:55:50 UTC (rev 20717)
@@ -35,7 +35,7 @@
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,8 +93,8 @@
revisionTypePropType = "byte";
revisionEndFieldName = getProperty(properties,
+
"org.hibernate.envers.audit_strategy_validity_end_rev_field_name",
"org.hibernate.envers.audit_strategy_valid_time_end_name",
- "org.hibernate.envers.audit_strategy_valid_time_end_name",
"REVEND");
customAuditTablesNames = new HashMap<String, String>();
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java
===================================================================
---
core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java 2010-09-26
19:12:41 UTC (rev 20716)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java 2010-09-26
19:55:50 UTC (rev 20717)
@@ -28,9 +28,11 @@
import java.util.Map;
import org.dom4j.Element;
-import org.hibernate.envers.configuration.AuditConfiguration;
+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.AuditEntitiesConfiguration;
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.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 @@
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());
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/OneAuditEntityQueryGenerator.java
===================================================================
---
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/OneAuditEntityQueryGenerator.java 2010-09-26
19:12:41 UTC (rev 20716)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/OneAuditEntityQueryGenerator.java 2010-09-26
19:55:50 UTC (rev 20717)
@@ -61,7 +61,7 @@
* 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
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/OneEntityQueryGenerator.java
===================================================================
---
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/OneEntityQueryGenerator.java 2010-09-26
19:12:41 UTC (rev 20716)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/OneEntityQueryGenerator.java 2010-09-26
19:55:50 UTC (rev 20717)
@@ -62,7 +62,7 @@
* 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
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/ThreeEntityQueryGenerator.java
===================================================================
---
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/ThreeEntityQueryGenerator.java 2010-09-26
19:12:41 UTC (rev 20716)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/ThreeEntityQueryGenerator.java 2010-09-26
19:55:50 UTC (rev 20717)
@@ -70,7 +70,7 @@
* 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 @@
* 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 @@
* 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 (
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/TwoEntityOneAuditedQueryGenerator.java
===================================================================
---
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/TwoEntityOneAuditedQueryGenerator.java 2010-09-26
19:12:41 UTC (rev 20716)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/TwoEntityOneAuditedQueryGenerator.java 2010-09-26
19:55:50 UTC (rev 20717)
@@ -68,7 +68,7 @@
* 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
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/TwoEntityQueryGenerator.java
===================================================================
---
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/TwoEntityQueryGenerator.java 2010-09-26
19:12:41 UTC (rev 20716)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/TwoEntityQueryGenerator.java 2010-09-26
19:55:50 UTC (rev 20717)
@@ -68,7 +68,7 @@
* 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 @@
* 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)
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/query/impl/EntitiesAtRevisionQuery.java
===================================================================
---
core/trunk/envers/src/main/java/org/hibernate/envers/query/impl/EntitiesAtRevisionQuery.java 2010-09-26
19:12:41 UTC (rev 20716)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/query/impl/EntitiesAtRevisionQuery.java 2010-09-26
19:55:50 UTC (rev 20717)
@@ -67,7 +67,7 @@
* 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
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/AuditStrategy.java
===================================================================
---
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/AuditStrategy.java 2010-09-26
19:12:41 UTC (rev 20716)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/AuditStrategy.java 2010-09-26
19:55:50 UTC (rev 20717)
@@ -49,7 +49,7 @@
* <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 @@
* @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 @@
* <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,
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/ValidTimeAuditStrategy.java
===================================================================
---
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/ValidTimeAuditStrategy.java 2010-09-26
19:12:41 UTC (rev 20716)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/ValidTimeAuditStrategy.java 2010-09-26
19:55:50 UTC (rev 20717)
@@ -1,135 +1,25 @@
package org.hibernate.envers.strategy;
-import java.io.Serializable;
-import java.util.List;
-import java.util.Map;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-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 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);
+ /**
+ * Default constructor. Log a warn message that this class is deprecated.
+ */
+ public ValidTimeAuditStrategy() {
+ log.warn("ValidTimeAuditStrategy is deprecated, please use ValidityAuditStrategy
instead");
}
-
- 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 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);
- }
- }
}
Added:
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/ValidityAuditStrategy.java
===================================================================
---
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/ValidityAuditStrategy.java
(rev 0)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/ValidityAuditStrategy.java 2010-09-26
19:55:50 UTC (rev 20717)
@@ -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);
+ }
+ }
+}
Modified: core/trunk/envers/src/test/resources/hibernate.test.cfg.xml
===================================================================
--- core/trunk/envers/src/test/resources/hibernate.test.cfg.xml 2010-09-26 19:12:41 UTC
(rev 20716)
+++ core/trunk/envers/src/test/resources/hibernate.test.cfg.xml 2010-09-26 19:55:50 UTC
(rev 20717)
@@ -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>-->
Modified: core/trunk/envers/src/test/resources/testng.xml
===================================================================
--- core/trunk/envers/src/test/resources/testng.xml 2010-09-26 19:12:41 UTC (rev 20716)
+++ core/trunk/envers/src/test/resources/testng.xml 2010-09-26 19:55:50 UTC (rev 20717)
@@ -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>