Author: adamw
Date: 2010-07-02 02:32:13 -0400 (Fri, 02 Jul 2010)
New Revision: 19888
Added:
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/AuditStrategy.java
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/DefaultAuditStrategy.java
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/ValidTimeAuditStrategy.java
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/configuration/AuditConfiguration.java
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/query/impl/AbstractAuditQuery.java
core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/AbstractAuditWorkUnit.java
core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/PersistentCollectionChangeWorkUnit.java
core/trunk/envers/src/main/java/org/hibernate/envers/tools/query/QueryBuilder.java
core/trunk/envers/src/test/java/org/hibernate/envers/test/AbstractEntityTest.java
core/trunk/envers/src/test/java/org/hibernate/envers/test/entities/customtype/CompositeTestUserType.java
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/manytomany/sametable/BasicSametable.java
core/trunk/envers/src/test/java/org/hibernate/envers/test/performance/AbstractPerformanceTest.java
core/trunk/envers/src/test/resources/hibernate.test.cfg.xml
core/trunk/envers/src/test/resources/testng.xml
Log:
HHH-3764:
- adding an end-revision column to the audit entities if the appropraite strategy is used
HHH-3765:
- filling in the end-revision column on audited entities changes
- applying patch by Stephanie Pau - thanks!
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/configuration/AuditConfiguration.java
===================================================================
---
core/trunk/envers/src/main/java/org/hibernate/envers/configuration/AuditConfiguration.java 2010-07-01
20:29:38 UTC (rev 19887)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/configuration/AuditConfiguration.java 2010-07-02
06:32:13 UTC (rev 19888)
@@ -27,10 +27,12 @@
import java.util.Properties;
import java.util.WeakHashMap;
+import org.hibernate.MappingException;
import org.hibernate.envers.entities.EntitiesConfigurations;
import org.hibernate.envers.revisioninfo.RevisionInfoNumberReader;
import org.hibernate.envers.revisioninfo.RevisionInfoQueryCreator;
import org.hibernate.envers.synchronization.AuditProcessManager;
+import org.hibernate.envers.strategy.AuditStrategy;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.AnnotationConfiguration;
@@ -38,11 +40,13 @@
/**
* @author Adam Warski (adam at warski dot org)
+ * @author Stephanie Pau at Markit Group Plc
*/
public class AuditConfiguration {
private final GlobalConfiguration globalCfg;
private final AuditEntitiesConfiguration auditEntCfg;
private final AuditProcessManager auditProcessManager;
+ private final AuditStrategy auditStrategy;
private final EntitiesConfigurations entCfg;
private final RevisionInfoQueryCreator revisionInfoQueryCreator;
private final RevisionInfoNumberReader revisionInfoNumberReader;
@@ -71,7 +75,11 @@
return revisionInfoNumberReader;
}
- @SuppressWarnings({"unchecked"})
+ public AuditStrategy getAuditStrategy() {
+ return auditStrategy;
+ }
+
+ @SuppressWarnings({ "unchecked" })
public AuditConfiguration(Configuration cfg) {
Properties properties = cfg.getProperties();
@@ -81,6 +89,14 @@
auditEntCfg = new AuditEntitiesConfiguration(properties,
revInfoCfgResult.getRevisionInfoEntityName());
globalCfg = new GlobalConfiguration(properties);
auditProcessManager = new
AuditProcessManager(revInfoCfgResult.getRevisionInfoGenerator());
+
+ try {
+ Class auditStrategyClass =
Thread.currentThread().getContextClassLoader().loadClass(auditEntCfg.getAuditStrategyName());
+ auditStrategy = (AuditStrategy) auditStrategyClass.newInstance();
+ } catch (Exception e) {
+ throw new MappingException(String.format("Unable to create
AuditStrategy[%s] instance." , auditEntCfg.getAuditStrategyName()));
+ }
+
revisionInfoQueryCreator = revInfoCfgResult.getRevisionInfoQueryCreator();
revisionInfoNumberReader = revInfoCfgResult.getRevisionInfoNumberReader();
entCfg = new EntitiesConfigurator().configure(cfg, reflectionManager, globalCfg,
auditEntCfg,
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-07-01
20:29:38 UTC (rev 19887)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/configuration/AuditEntitiesConfiguration.java 2010-07-02
06:32:13 UTC (rev 19888)
@@ -25,18 +25,28 @@
import static org.hibernate.envers.tools.Tools.getProperty;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
+import org.hibernate.MappingException;
+import org.hibernate.envers.strategy.DefaultAuditStrategy;
+import org.hibernate.envers.strategy.ValidTimeAuditStrategy;
+
/**
* Configuration of versions entities - names of fields, entities and tables created to
store versioning information.
* @author Adam Warski (adam at warski dot org)
+ * @author Stephanie Pau at Markit Group Plc
*/
public class AuditEntitiesConfiguration {
private final String auditTablePrefix;
private final String auditTableSuffix;
+ private final String auditStrategyName;
private final String originalIdPropName;
private final String revisionFieldName;
@@ -50,6 +60,8 @@
private final Map<String, String> customAuditTablesNames;
+ private final String revisionEndFieldName;
+
public AuditEntitiesConfiguration(Properties properties, String
revisionInfoEntityName) {
this.revisionInfoEntityName = revisionInfoEntityName;
@@ -62,6 +74,11 @@
"org.hibernate.envers.auditTableSuffix",
"_AUD");
+ auditStrategyName = getProperty(properties,
+ "org.hibernate.envers.audit_strategy",
+ "org.hibernate.envers.audit_strategy",
+ DefaultAuditStrategy.class.getName());
+
originalIdPropName = "originalId";
revisionFieldName = getProperty(properties,
@@ -75,6 +92,11 @@
"REVTYPE");
revisionTypePropType = "byte";
+ revisionEndFieldName = getProperty(properties,
+ "org.hibernate.envers.audit_strategy_valid_time_end_name",
+ "org.hibernate.envers.audit_strategy_valid_time_end_name",
+ "REVEND");
+
customAuditTablesNames = new HashMap<String, String>();
revisionNumberPath = originalIdPropName + "." + revisionFieldName +
".id";
@@ -133,4 +155,12 @@
return customHistoryTableName;
}
+
+ public String getAuditStrategyName() {
+ return auditStrategyName;
+ }
+
+ public String getRevisionEndFieldName() {
+ return revisionEndFieldName;
+ }
}
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-07-01
20:29:38 UTC (rev 19887)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java 2010-07-02
06:32:13 UTC (rev 19888)
@@ -38,6 +38,7 @@
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.ValidTimeAuditStrategy;
import org.hibernate.envers.tools.StringTools;
import org.hibernate.envers.tools.Triple;
import org.hibernate.envers.RelationTargetAuditMode;
@@ -53,6 +54,7 @@
* @author Adam Warski (adam at warski dot org)
* @author Sebastian Komander
* @author Tomasz Bech
+ * @author Stephanie Pau at Markit Group Plc
*/
public final class AuditMetadataGenerator {
private static final Logger log =
LoggerFactory.getLogger(AuditMetadataGenerator.class);
@@ -124,8 +126,23 @@
Element revTypeProperty = MetadataTools.addProperty(any_mapping,
verEntCfg.getRevisionTypePropName(),
verEntCfg.getRevisionTypePropType(), true, false);
revTypeProperty.addAttribute("type",
"org.hibernate.envers.entities.RevisionTypeType");
+
+ // Adding the end revision, if appropriate
+ addEndRevision(any_mapping);
}
+ private void addEndRevision(Element any_mapping) {
+ // Add the end-revision field, if the appropriate strategy is used.
+ if
(ValidTimeAuditStrategy.class.getName().equals(verEntCfg.getAuditStrategyName())) {
+ Element end_rev_mapping = (Element) revisionInfoRelationMapping.clone();
+ end_rev_mapping.setName("many-to-one");
+ end_rev_mapping.addAttribute("name",
verEntCfg.getRevisionEndFieldName());
+ MetadataTools.addOrModifyColumn(end_rev_mapping,
verEntCfg.getRevisionEndFieldName());
+
+ any_mapping.add(end_rev_mapping);
+ }
+ }
+
@SuppressWarnings({"unchecked"})
void addValue(Element parent, Value value, CompositeMapperBuilder currentMapper,
String entityName,
EntityXmlMappingData xmlMappingData, PropertyAuditingData
propertyAuditingData,
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/query/impl/AbstractAuditQuery.java
===================================================================
---
core/trunk/envers/src/main/java/org/hibernate/envers/query/impl/AbstractAuditQuery.java 2010-07-01
20:29:38 UTC (rev 19887)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/query/impl/AbstractAuditQuery.java 2010-07-02
06:32:13 UTC (rev 19888)
@@ -24,9 +24,7 @@
package org.hibernate.envers.query.impl;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
@@ -80,16 +78,8 @@
}
protected List buildAndExecuteQuery() {
- StringBuilder querySb = new StringBuilder();
- Map<String, Object> queryParamValues = new HashMap<String,
Object>();
+ Query query = qb.toQuery(versionsReader.getSession());
- qb.build(querySb, queryParamValues);
-
- Query query = versionsReader.getSession().createQuery(querySb.toString());
- for (Map.Entry<String, Object> paramValue : queryParamValues.entrySet()) {
- query.setParameter(paramValue.getKey(), paramValue.getValue());
- }
-
setQueryProperties(query);
return query.list();
Added: core/trunk/envers/src/main/java/org/hibernate/envers/strategy/AuditStrategy.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/strategy/AuditStrategy.java
(rev 0)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/AuditStrategy.java 2010-07-02
06:32:13 UTC (rev 19888)
@@ -0,0 +1,39 @@
+package org.hibernate.envers.strategy;
+
+import org.hibernate.Session;
+import org.hibernate.envers.configuration.AuditConfiguration;
+import org.hibernate.envers.entities.mapper.PersistentCollectionChangeData;
+
+import java.io.Serializable;
+
+/**
+ * Behaviours of different audit strategy for populating audit data.
+ *
+ * @author Stephanie Pau
+ * @author Adam Warski (adam at warski dot org)
+ */
+public interface AuditStrategy {
+ /**
+ * 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 auditCfg Audit configuration
+ * @param id Id of the entity.
+ * @param data Audit data to persist
+ * @param revision Current revision data
+ */
+ void perform(Session session, String entityName, AuditConfiguration auditCfg,
Serializable id, Object data,
+ Object revision);
+
+ /**
+ * Perform the persistence of audited data for collection ("middle")
entities.
+ *
+ * @param session Session, which can be used to persist the data.
+ * @param auditCfg Audit configuration
+ * @param persistentCollectionChangeData Collection change data to be persisted.
+ * @param revision Current revision data
+ */
+ void performCollectionChange(Session session, AuditConfiguration auditCfg,
+ PersistentCollectionChangeData
persistentCollectionChangeData, Object revision);
+}
Property changes on:
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/AuditStrategy.java
___________________________________________________________________
Name: svn:executable
+ *
Added:
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/DefaultAuditStrategy.java
===================================================================
---
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/DefaultAuditStrategy.java
(rev 0)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/DefaultAuditStrategy.java 2010-07-02
06:32:13 UTC (rev 19888)
@@ -0,0 +1,25 @@
+package org.hibernate.envers.strategy;
+
+import org.hibernate.Session;
+import org.hibernate.envers.configuration.AuditConfiguration;
+import org.hibernate.envers.entities.mapper.PersistentCollectionChangeData;
+
+import java.io.Serializable;
+
+/**
+ * Default strategy is to simply persist the audit data.
+ *
+ * @author Adam Warski
+ * @author Stephanie Pau
+ */
+public class DefaultAuditStrategy implements AuditStrategy {
+ public void perform(Session session, String entityName, AuditConfiguration auditCfg,
Serializable id, Object data,
+ Object revision) {
+ session.save(auditCfg.getAuditEntCfg().getAuditEntityName(entityName), data);
+ }
+
+ public void performCollectionChange(Session session, AuditConfiguration auditCfg,
+ PersistentCollectionChangeData
persistentCollectionChangeData, Object revision) {
+ session.save(persistentCollectionChangeData.getEntityName(),
persistentCollectionChangeData.getData());
+ }
+}
Property changes on:
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/DefaultAuditStrategy.java
___________________________________________________________________
Name: svn:executable
+ *
Added:
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/ValidTimeAuditStrategy.java
===================================================================
---
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/ValidTimeAuditStrategy.java
(rev 0)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/ValidTimeAuditStrategy.java 2010-07-02
06:32:13 UTC (rev 19888)
@@ -0,0 +1,105 @@
+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.entities.mapper.PersistentCollectionChangeData;
+import org.hibernate.envers.entities.mapper.id.IdMapper;
+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.
+ *
+ * @author Stephanie Pau
+ * @author Adam Warski (adam at warski dot org)
+ */
+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);
+
+ // 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());
+ }
+
+ @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);
+ }
+ }
+}
Property changes on:
core/trunk/envers/src/main/java/org/hibernate/envers/strategy/ValidTimeAuditStrategy.java
___________________________________________________________________
Name: svn:executable
+ *
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/AbstractAuditWorkUnit.java
===================================================================
---
core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/AbstractAuditWorkUnit.java 2010-07-01
20:29:38 UTC (rev 19887)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/AbstractAuditWorkUnit.java 2010-07-02
06:32:13 UTC (rev 19888)
@@ -33,15 +33,18 @@
import org.hibernate.Session;
import org.hibernate.engine.SessionImplementor;
+import org.hibernate.envers.strategy.AuditStrategy;
/**
* @author Adam Warski (adam at warski dot org)
+ * @author Stephanie Pau at Markit Group Plc
*/
public abstract class AbstractAuditWorkUnit implements AuditWorkUnit {
protected final SessionImplementor sessionImplementor;
protected final AuditConfiguration verCfg;
protected final Serializable id;
protected final String entityName;
+ protected final AuditStrategy auditStrategy;
private Object performedData;
@@ -51,6 +54,7 @@
this.verCfg = verCfg;
this.id = id;
this.entityName = entityName;
+ this.auditStrategy = verCfg.getAuditStrategy();
}
protected void fillDataWithId(Map<String, Object> data, Object revision,
RevisionType revisionType) {
@@ -67,7 +71,7 @@
public void perform(Session session, Object revisionData) {
Map<String, Object> data = generateData(revisionData);
- session.save(verCfg.getAuditEntCfg().getAuditEntityName(getEntityName()), data);
+ auditStrategy.perform(session, getEntityName(), verCfg, id, data, revisionData);
setPerformed(data);
}
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/PersistentCollectionChangeWorkUnit.java
===================================================================
---
core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/PersistentCollectionChangeWorkUnit.java 2010-07-01
20:29:38 UTC (rev 19887)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/PersistentCollectionChangeWorkUnit.java 2010-07-02
06:32:13 UTC (rev 19888)
@@ -29,6 +29,7 @@
import java.util.HashMap;
import java.util.ArrayList;
+import org.hibernate.envers.RevisionType;
import org.hibernate.envers.configuration.AuditConfiguration;
import org.hibernate.envers.configuration.AuditEntitiesConfiguration;
import org.hibernate.envers.entities.mapper.PersistentCollectionChangeData;
@@ -84,7 +85,7 @@
((Map<String, Object>)
persistentCollectionChangeData.getData().get(entitiesCfg.getOriginalIdPropName()))
.put(entitiesCfg.getRevisionFieldName(), revisionData);
- session.save(persistentCollectionChangeData.getEntityName(),
persistentCollectionChangeData.getData());
+ auditStrategy.performCollectionChange(session, verCfg,
persistentCollectionChangeData, revisionData);
}
}
@@ -137,13 +138,24 @@
// Including only those original changes, which are not overshadowed by new
ones.
for (PersistentCollectionChangeData originalCollectionChangeData :
original.getCollectionChanges()) {
- if
(!newChangesIdMap.containsKey(getOriginalId(originalCollectionChangeData))) {
+ Object originalOriginalId = getOriginalId(originalCollectionChangeData);
+ if (!newChangesIdMap.containsKey(originalOriginalId)) {
mergedChanges.add(originalCollectionChangeData);
+ } else {
+ // If the changes collide, checking if the first one isn't a DEL,
and the second a subsequent ADD
+ // If so, removing the change alltogether.
+ String revTypePropName =
verCfg.getAuditEntCfg().getRevisionTypePropName();
+ if
(RevisionType.ADD.equals(newChangesIdMap.get(originalOriginalId).getData().get(
+ revTypePropName)) &&
RevisionType.DEL.equals(originalCollectionChangeData.getData().get(
+ revTypePropName))) {
+ newChangesIdMap.remove(originalOriginalId);
+ }
}
}
- // Finally adding all of the new changes to the end of the list
- mergedChanges.addAll(getCollectionChanges());
+ // Finally adding all of the new changes to the end of the list (the map
values may differ from
+ // getCollectionChanges() because of the last operation above).
+ mergedChanges.addAll(newChangesIdMap.values());
return new PersistentCollectionChangeWorkUnit(sessionImplementor, entityName,
verCfg, id, mergedChanges,
referencingPropertyName);
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/tools/query/QueryBuilder.java
===================================================================
---
core/trunk/envers/src/main/java/org/hibernate/envers/tools/query/QueryBuilder.java 2010-07-01
20:29:38 UTC (rev 19887)
+++
core/trunk/envers/src/main/java/org/hibernate/envers/tools/query/QueryBuilder.java 2010-07-02
06:32:13 UTC (rev 19888)
@@ -24,9 +24,12 @@
package org.hibernate.envers.tools.query;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.hibernate.Query;
+import org.hibernate.Session;
import org.hibernate.envers.tools.MutableInteger;
import org.hibernate.envers.tools.Pair;
import org.hibernate.envers.tools.StringTools;
@@ -197,4 +200,18 @@
return orderList;
}
+
+ public Query toQuery(Session session) {
+ StringBuilder querySb = new StringBuilder();
+ Map<String, Object> queryParamValues = new HashMap<String,
Object>();
+
+ build(querySb, queryParamValues);
+
+ Query query = session.createQuery(querySb.toString());
+ for (Map.Entry<String, Object> paramValue : queryParamValues.entrySet()) {
+ query.setParameter(paramValue.getKey(), paramValue.getValue());
+ }
+
+ return query;
+ }
}
Modified:
core/trunk/envers/src/test/java/org/hibernate/envers/test/AbstractEntityTest.java
===================================================================
---
core/trunk/envers/src/test/java/org/hibernate/envers/test/AbstractEntityTest.java 2010-07-01
20:29:38 UTC (rev 19887)
+++
core/trunk/envers/src/test/java/org/hibernate/envers/test/AbstractEntityTest.java 2010-07-02
06:32:13 UTC (rev 19888)
@@ -30,9 +30,7 @@
import org.hibernate.envers.AuditReader;
import org.hibernate.envers.AuditReaderFactory;
import org.hibernate.envers.event.AuditEventListener;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.AfterClass;
+import org.testng.annotations.*;
import org.hibernate.ejb.Ejb3Configuration;
import org.hibernate.event.*;
@@ -78,17 +76,23 @@
}
@BeforeClass
- public void init() throws IOException {
- init(true);
+ @Parameters("auditStrategy")
+ public void init(@Optional String auditStrategy) throws IOException {
+ init(true, auditStrategy);
}
- protected void init(boolean audited) throws IOException {
+ protected void init(boolean audited, String auditStrategy) throws IOException {
this.audited = audited;
cfg = new Ejb3Configuration();
if (audited) {
initListeners();
}
+
+ if (auditStrategy != null && !"".equals(auditStrategy)) {
+ cfg.setProperty("org.hibernate.envers.audit_strategy",
auditStrategy);
+ }
+
cfg.configure("hibernate.test.cfg.xml");
configure(cfg);
emf = cfg.buildEntityManagerFactory();
Modified:
core/trunk/envers/src/test/java/org/hibernate/envers/test/entities/customtype/CompositeTestUserType.java
===================================================================
---
core/trunk/envers/src/test/java/org/hibernate/envers/test/entities/customtype/CompositeTestUserType.java 2010-07-01
20:29:38 UTC (rev 19887)
+++
core/trunk/envers/src/test/java/org/hibernate/envers/test/entities/customtype/CompositeTestUserType.java 2010-07-02
06:32:13 UTC (rev 19888)
@@ -90,9 +90,6 @@
public Object nullSafeGet(final ResultSet rs, final String[] names,
final SessionImplementor session,
final Object owner) throws HibernateException, SQLException
{
- if (rs.wasNull()) {
- return null;
- }
final String prop1 = rs.getString(names[0]);
if (prop1 == null) {
return null;
Modified:
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/manytomany/sametable/BasicSametable.java
===================================================================
---
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/manytomany/sametable/BasicSametable.java 2010-07-01
20:29:38 UTC (rev 19887)
+++
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/manytomany/sametable/BasicSametable.java 2010-07-02
06:32:13 UTC (rev 19888)
@@ -66,7 +66,7 @@
session.createSQLQuery("DROP TABLE children").executeUpdate();
session.createSQLQuery("CREATE TABLE children(parent_id integer, child1_id
integer NULL, child2_id integer NULL)").executeUpdate();
session.createSQLQuery("DROP TABLE children_AUD").executeUpdate();
- session.createSQLQuery("CREATE TABLE children_AUD(REV integer NOT NULL,
REVTYPE tinyint, " +
+ session.createSQLQuery("CREATE TABLE children_AUD(REV integer NOT NULL,
REVEND integer, REVTYPE tinyint, " +
"parent_id integer, child1_id integer NULL, child2_id integer
NULL)").executeUpdate();
em.getTransaction().commit();
em.clear();
Modified:
core/trunk/envers/src/test/java/org/hibernate/envers/test/performance/AbstractPerformanceTest.java
===================================================================
---
core/trunk/envers/src/test/java/org/hibernate/envers/test/performance/AbstractPerformanceTest.java 2010-07-01
20:29:38 UTC (rev 19887)
+++
core/trunk/envers/src/test/java/org/hibernate/envers/test/performance/AbstractPerformanceTest.java 2010-07-02
06:32:13 UTC (rev 19888)
@@ -88,11 +88,11 @@
List<Long> unauditedRuns = new ArrayList<Long>();
List<Long> auditedRuns = new ArrayList<Long>();
- init(true);
+ init(true, null);
long audited = run(numberOfRuns, auditedRuns);
close();
- init(false);
+ init(false, null);
long unaudited = run(numberOfRuns, unauditedRuns);
close();
Modified: core/trunk/envers/src/test/resources/hibernate.test.cfg.xml
===================================================================
--- core/trunk/envers/src/test/resources/hibernate.test.cfg.xml 2010-07-01 20:29:38 UTC
(rev 19887)
+++ core/trunk/envers/src/test/resources/hibernate.test.cfg.xml 2010-07-02 06:32:13 UTC
(rev 19888)
@@ -23,6 +23,8 @@
<!--<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="hibernate.jdbc.batch_size">100</property>-->
<!--<event type="post-insert">
Modified: core/trunk/envers/src/test/resources/testng.xml
===================================================================
--- core/trunk/envers/src/test/resources/testng.xml 2010-07-01 20:29:38 UTC (rev 19887)
+++ core/trunk/envers/src/test/resources/testng.xml 2010-07-02 06:32:13 UTC (rev 19888)
@@ -1,8 +1,5 @@
-<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
-
-<suite name="Envers">
- <test name="All">
- <packages>
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" [
+ <!ENTITY packages '
<package name="org.hibernate.envers.test.integration.accesstype"
/>
<package
name="org.hibernate.envers.test.integration.auditReader" />
<package name="org.hibernate.envers.test.integration.basic"
/>
@@ -71,6 +68,19 @@
<package
name="org.hibernate.envers.test.integration.secondary.ids" />
<package
name="org.hibernate.envers.test.integration.serialization" />
<package name="org.hibernate.envers.test.integration.superclass"
/>
+ '>
+]>
+
+<suite name="Envers">
+ <test name="All">
+ <packages>
+ &packages;
</packages>
</test>
+ <test name="ValidTimeAuditStrategy">
+ <parameter name="auditStrategy"
value="org.hibernate.envers.strategy.ValidTimeAuditStrategy" />
+ <packages>
+ &packages;
+ </packages>
+ </test>
</suite>