[hibernate-commits] Hibernate SVN: r20717 - in core/trunk/envers/src: main/java/org/hibernate/envers/configuration/metadata and 4 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Sun Sep 26 15:55:50 EDT 2010


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>



More information about the hibernate-commits mailing list