Added methods and tests to recover changes to data
authorben.clark <ben.clark@localhost>
Fri, 6 Nov 2009 15:06:01 +0000 (15:06 +0000)
committerben.clark <ben.clark@localhost>
Fri, 6 Nov 2009 15:06:01 +0000 (15:06 +0000)
.gitattributes
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/common/IVersionableDao.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/common/VersionableDaoBase.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/view/AuditEventDao.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/view/IAuditEventDao.java
cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImplTest.java
cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/view/AuditEventDaoTest.java [new file with mode: 0644]
cdmlib-persistence/src/test/resources/dbscripts/001_cdm.ddl
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/common/IdentifiableDaoBaseTest.xml
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImplTest.testFindDeleted.xml
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/view/AuditEventDaoTest.xml [new file with mode: 0644]

index 42bb319f78ff098f6c173eaf1f95be9d6e97055a..f93210219e2c3c8ef8461f0cc862a0bfabdf6c6a 100644 (file)
@@ -1925,6 +1925,7 @@ cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/name
 cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/reference/ReferenceDaoHibernateImplTest.java -text
 cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImplTest.java -text
 cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonNodeDaoHibernateImplTest.java -text
+cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/view/AuditEventDaoTest.java -text
 cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/hibernate/CacheStrategyGeneratorTest.java -text
 cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/hibernate/CdmDeleteListenerTest.java -text
 cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/test/function/Datasource.java -text
@@ -2004,6 +2005,7 @@ cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate
 cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImplTest.testGetTaxaByNameAndArea.xml -text
 cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImplTest.xml -text
 cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonNodeDaoHibernateImplTest.xml -text
+cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/view/AuditEventDaoTest.xml -text
 cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/hibernate/CacheStrategyGeneratorTest.testOnSaveOrUpdateAgents-result.xml -text
 cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/hibernate/CacheStrategyGeneratorTest.testOnSaveOrUpdateNames-result.xml -text
 cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/hibernate/CacheStrategyGeneratorTest.xml -text
index 0b451d8964c192117aaf5e92b6fce31f5640ebaa..a72f05349b349020d7643c46444e590ccb867656 100644 (file)
@@ -11,7 +11,10 @@ package eu.etaxonomy.cdm.persistence.dao.common;
 
 import java.util.List;
 
+import org.hibernate.envers.query.criteria.AuditCriterion;
+
 import eu.etaxonomy.cdm.model.common.VersionableEntity;
+import eu.etaxonomy.cdm.model.view.AuditEvent;
 import eu.etaxonomy.cdm.model.view.AuditEventRecord;
 
 public interface IVersionableDao<T extends VersionableEntity> extends ICdmEntityDao<T> {
@@ -62,4 +65,33 @@ public interface IVersionableDao<T extends VersionableEntity> extends ICdmEntity
         * @return a record of the previous audit event to affect t, or null if the current event is the first to affect t
         */
        public AuditEventRecord<T> getPreviousAuditEvent(T t);
+       
+       /**
+        * Returns a count of the total number of audit events affecting objects of class T, optionally restricted to objects of
+        * class clazz, the AuditEvents from and to, inclusive, optionally filtered by other criteria
+        * 
+        * @param clazz Restrict the results returned to objects of this class
+        * @param from The audit event to start from (or pass null to start from the beginning of the recordset)
+        * @param to The audit event to continue until (or pass null to return audit events up to the time of the query)
+        * @param criteria Extra criteria to filter by
+        * @return the count of audit events
+        */
+       public Integer countAuditEvents(Class<? extends T> clazz,AuditEvent from,AuditEvent to,List<AuditCriterion> criteria);
+       
+       /**
+        * Returns a list of all audit events occurring to objects of type T, optionally restricted to objects of type clazz
+        * between the AuditEvents from and to, inclusive, optionally filtered by other criteria
+        * 
+        * @param clazz Restrict the results returned to objects of this class
+        * @param from The audit event to start from (inclusive, or pass null to start from the beginning of the recordset)
+        * @param to The audit event to continue until (exclusive, or pass null to return audit events up to the time of the query)
+        * @param criteria Extra criteria to filter by
+        * @param pageSize The maximum number of objects returned (can be null for all matching objects)
+        * @param pageNumber The offset (in pageSize chunks) from the start of the result set (0 - based, 
+        *                   can be null, equivalent of starting at the beginning of the recordset)
+        * @param sort Sort the events either forwards or backwards in time
+        * @param propertyPaths properties to be initialized
+        * @return
+        */
+       public List<AuditEventRecord<T>> getAuditEvents(Class<? extends T> clazz, AuditEvent from,AuditEvent to,List<AuditCriterion> criteria, Integer pageSize, Integer pageNumber,AuditEventSort sort,List<String> propertyPaths);
 }
index cb4157e27e2eaa11f2167c52e7bea46989513948..e787caddf3c6f798251b3bafc94246714592cc7d 100644 (file)
@@ -17,10 +17,12 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;\r
 import org.apache.lucene.search.Sort;\r
 import org.apache.lucene.search.SortField;\r
+import org.hibernate.criterion.Criterion;\r
 import org.hibernate.envers.AuditReader;\r
 import org.hibernate.envers.AuditReaderFactory;\r
 import org.hibernate.envers.query.AuditEntity;\r
 import org.hibernate.envers.query.AuditQuery;\r
+import org.hibernate.envers.query.criteria.AuditCriterion;\r
 import org.hibernate.envers.query.order.AuditOrder;\r
 import org.hibernate.search.FullTextQuery;\r
 import org.joda.time.DateTime;\r
@@ -269,4 +271,80 @@ public abstract class VersionableDaoBase<T extends VersionableEntity> extends Cd
                    return auditEvents.get(0);\r
                }\r
        }\r
+\r
+       public Integer countAuditEvents(Class<? extends T> clazz, AuditEvent from,      AuditEvent to, List<AuditCriterion> criteria) {\r
+               AuditQuery query = null;\r
+               \r
+               if(clazz == null) {\r
+                  query = getAuditReader().createQuery().forRevisionsOfEntity(type, false, true);\r
+               } else {\r
+                  query = getAuditReader().createQuery().forRevisionsOfEntity(clazz, false, true);\r
+               }\r
+               \r
+               if(from != null) {\r
+                       query.add(AuditEntity.revisionNumber().ge(from.getRevisionNumber()));\r
+               } \r
+               \r
+               if(to != null && !to.equals(AuditEvent.CURRENT_VIEW)) {\r
+                       query.add(AuditEntity.revisionNumber().lt(to.getRevisionNumber()));\r
+               } \r
+               \r
+               addCriteria(query,criteria);\r
+               \r
+               query.addProjection(AuditEntity.property("id").count());\r
+               \r
+               return ((Long)query.getSingleResult()).intValue();\r
+       }\r
+\r
+       protected void addCriteria(AuditQuery query, List<AuditCriterion> criteria) {\r
+               if(criteria != null) {\r
+                       for(AuditCriterion c : criteria) {\r
+                               query.add(c);\r
+                       }\r
+               }\r
+       }\r
+\r
+       public List<AuditEventRecord<T>> getAuditEvents(Class<? extends T> clazz,AuditEvent from, AuditEvent to, List<AuditCriterion> criteria, Integer pageSize, Integer pageNumber, AuditEventSort sort,      List<String> propertyPaths) {\r
+        AuditQuery query = null;\r
+               \r
+               if(clazz == null) {\r
+                  query = getAuditReader().createQuery().forRevisionsOfEntity(type, false, true);\r
+               } else {\r
+                  query = getAuditReader().createQuery().forRevisionsOfEntity(clazz, false, true);\r
+               }\r
+               \r
+               if(from != null) {\r
+                       query.add(AuditEntity.revisionNumber().ge(from.getRevisionNumber()));\r
+               } \r
+               \r
+               if(to != null && !to.equals(AuditEvent.CURRENT_VIEW)) {\r
+                       query.add(AuditEntity.revisionNumber().lt(to.getRevisionNumber()));\r
+               } \r
+               \r
+               addCriteria(query,criteria);\r
+               \r
+               if(pageSize != null) {\r
+                   query.setMaxResults(pageSize);\r
+                   if(pageNumber != null) {\r
+                       query.setFirstResult(pageNumber * pageSize);\r
+                   } else {\r
+                       query.setFirstResult(0);\r
+                   }\r
+               }\r
+               \r
+               /**\r
+         * At the moment we need to transform the data manually\r
+         */\r
+        List<Object[]> objs = (List<Object[]>)query.getResultList();\r
+        List<AuditEventRecord<T>> records = new ArrayList<AuditEventRecord<T>>();\r
+        \r
+        for(Object[] obj : objs) {\r
+               records.add(new AuditEventRecordImpl<T>(obj));\r
+        }\r
+        \r
+        for(AuditEventRecord<T> record : records) {\r
+               defaultBeanInitializer.initialize(record.getAuditableObject(), propertyPaths);\r
+        }\r
+               return records;\r
+       }\r
 }\r
index 64b26473364b2a84b40b0e46ce386ca303a7f9a4..d0ded46be9e133ffeef733f17819862c253e50bb 100644 (file)
@@ -13,6 +13,9 @@ import java.util.List;
 import java.util.UUID;
 
 import org.hibernate.Query;
+import org.hibernate.envers.AuditReader;
+import org.hibernate.envers.AuditReaderFactory;
+import org.joda.time.DateTime;
 import org.springframework.stereotype.Repository;
 
 import eu.etaxonomy.cdm.model.view.AuditEvent;
@@ -22,6 +25,10 @@ import eu.etaxonomy.cdm.persistence.view.IAuditEventDao;
 
 @Repository
 public class AuditEventDao extends DaoBase implements IAuditEventDao {
+       
+       protected AuditReader getAuditReader() {
+               return AuditReaderFactory.get(getSession());
+       }
 
        public int count() {
                Query query = getSession().createQuery("select count(auditEvent) from AuditEvent auditEvent");
@@ -83,4 +90,9 @@ public class AuditEventDao extends DaoBase implements IAuditEventDao {
                
                return (List<AuditEvent>)query.list();
        }
+
+       public AuditEvent findByDate(DateTime dateTime) {
+               Number id = getAuditReader().getRevisionNumberForDate(dateTime.toDate());
+               return (AuditEvent)getSession().load(AuditEvent.class, id);
+       }
 }
index 5760cb90158c88f2614abc12c46da72346dca6f7..1dedaba3dfaf18b10dbcf94243085f473ee847a3 100644 (file)
@@ -12,6 +12,8 @@ package eu.etaxonomy.cdm.persistence.view;
 import java.util.List;
 import java.util.UUID;
 
+import org.joda.time.DateTime;
+
 import eu.etaxonomy.cdm.model.view.AuditEvent;
 import eu.etaxonomy.cdm.persistence.dao.common.AuditEventSort;
 
@@ -78,4 +80,11 @@ public interface IAuditEventDao {
      * @return true if an AuditEvent with a matching uuid exists in the database, false otherwise
      */
     public boolean exists(UUID uuid);
+
+    /**
+     * Returns the AuditEvent that represents the given DateTime
+     * @param dateTime
+     * @return an AuditEvent object
+     */
+       public AuditEvent findByDate(DateTime dateTime);
 }
index fc5f96a8eb0f6d155b799f64d73f36ac058c5275..a59b57ca0078601f03846ca66e9f8a2e92357575 100644 (file)
@@ -25,6 +25,8 @@ import java.util.Set;
 import java.util.UUID;\r
 \r
 import org.hibernate.Hibernate;\r
+import org.hibernate.envers.query.AuditEntity;\r
+import org.hibernate.envers.query.criteria.AuditCriterion;\r
 import org.junit.After;\r
 import org.junit.Before;\r
 import org.junit.Ignore;\r
@@ -809,4 +811,37 @@ public class TaxonDaoHibernateImplTest extends CdmTransactionalIntegrationTest {
        TaxonomicTree taxonomicTree = taxonomicTreeDao.findByUuid(taxonomicTreeUuid);\r
                assertNotNull(taxonDao.getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByTaxonomicTree(taxonomicTree));\r
        }\r
+    \r
+    @Test\r
+    @DataSet("TaxonDaoHibernateImplTest.testFindDeleted.xml")\r
+    public void testGetAuditEventsByType() {\r
+       \r
+       List<String> propertyPaths = new ArrayList<String>();\r
+       propertyPaths.add("name");\r
+       propertyPaths.add("createdBy");\r
+       propertyPaths.add("updatedBy");\r
+       \r
+       List<AuditEventRecord<TaxonBase>> auditEvents = taxonDao.getAuditEvents(TaxonBase.class, previousAuditEvent, mostRecentAuditEvent, null,null, null, AuditEventSort.FORWARDS, propertyPaths);\r
+       assertNotNull("getAuditEvents should return a list",auditEvents);\r
+       assertFalse("the list should not be empty",auditEvents.isEmpty());\r
+       assertEquals("There should be thirty eight AuditEventRecords in the list",38, auditEvents.size());\r
+    }\r
+    \r
+    @Test\r
+    @DataSet("TaxonDaoHibernateImplTest.testFindDeleted.xml")\r
+    public void testGetAuditEventsByTypeWithRestrictions() {\r
+       \r
+       List<String> propertyPaths = new ArrayList<String>();\r
+       propertyPaths.add("name");\r
+       propertyPaths.add("createdBy");\r
+       propertyPaths.add("updatedBy");\r
+       \r
+       List<AuditCriterion> criteria = new ArrayList<AuditCriterion>();\r
+       criteria.add(AuditEntity.property("lsid_lsid").isNotNull());\r
+       \r
+       List<AuditEventRecord<TaxonBase>> auditEvents = taxonDao.getAuditEvents(TaxonBase.class, previousAuditEvent, mostRecentAuditEvent, criteria,null, null, AuditEventSort.FORWARDS, propertyPaths);\r
+       assertNotNull("getAuditEvents should return a list",auditEvents);\r
+       assertFalse("the list should not be empty",auditEvents.isEmpty());\r
+       assertEquals("There should be one AuditEventRecord in the list",1, auditEvents.size());\r
+    }\r
 }\r
diff --git a/cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/view/AuditEventDaoTest.java b/cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/view/AuditEventDaoTest.java
new file mode 100644 (file)
index 0000000..7c69991
--- /dev/null
@@ -0,0 +1,100 @@
+/**\r
+* Copyright (C) 2009 EDIT\r
+* European Distributed Institute of Taxonomy\r
+* http://www.e-taxonomy.eu\r
+*\r
+* The contents of this file are subject to the Mozilla Public License Version 1.1\r
+* See LICENSE.TXT at the top of this package for the full license terms.\r
+*/ \r
+\r
+package eu.etaxonomy.cdm.persistence.dao.hibernate.view;\r
+\r
+import static junit.framework.Assert.assertEquals;\r
+import static junit.framework.Assert.assertFalse;\r
+import static junit.framework.Assert.assertNotNull;\r
+import static junit.framework.Assert.assertSame;\r
+import static junit.framework.Assert.assertTrue;\r
+import static org.junit.Assert.assertNull;\r
+import static org.junit.Assert.fail;\r
+\r
+import java.io.FileOutputStream;\r
+import java.util.ArrayList;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+import java.util.UUID;\r
+\r
+import org.hibernate.Hibernate;\r
+import org.hibernate.envers.query.AuditEntity;\r
+import org.hibernate.envers.query.criteria.AuditCriterion;\r
+import org.joda.time.DateTime;\r
+import org.junit.After;\r
+import org.junit.Before;\r
+import org.junit.Ignore;\r
+import org.junit.Test;\r
+import org.unitils.dbunit.annotation.DataSet;\r
+import org.unitils.dbunit.annotation.ExpectedDataSet;\r
+import org.unitils.spring.annotation.SpringBeanByType;\r
+\r
+import eu.etaxonomy.cdm.model.description.DescriptionElementBase;\r
+import eu.etaxonomy.cdm.model.description.Distribution;\r
+import eu.etaxonomy.cdm.model.description.TaxonDescription;\r
+import eu.etaxonomy.cdm.model.location.NamedArea;\r
+import eu.etaxonomy.cdm.model.name.NonViralName;\r
+import eu.etaxonomy.cdm.model.name.Rank;\r
+import eu.etaxonomy.cdm.model.name.TaxonNameBase;\r
+import eu.etaxonomy.cdm.model.reference.ReferenceBase;\r
+import eu.etaxonomy.cdm.model.taxon.Synonym;\r
+import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;\r
+import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;\r
+import eu.etaxonomy.cdm.model.taxon.Taxon;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonBase;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonomicTree;\r
+import eu.etaxonomy.cdm.model.view.AuditEvent;\r
+import eu.etaxonomy.cdm.model.view.AuditEventRecord;\r
+import eu.etaxonomy.cdm.model.view.context.AuditEventContextHolder;\r
+import eu.etaxonomy.cdm.persistence.dao.common.AuditEventSort;\r
+import eu.etaxonomy.cdm.persistence.dao.common.IDefinedTermDao;\r
+import eu.etaxonomy.cdm.persistence.dao.reference.IReferenceDao;\r
+import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;\r
+import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonomicTreeDao;\r
+import eu.etaxonomy.cdm.persistence.fetch.CdmFetch;\r
+import eu.etaxonomy.cdm.persistence.query.GroupByCount;\r
+import eu.etaxonomy.cdm.persistence.query.GroupByDate;\r
+import eu.etaxonomy.cdm.persistence.query.Grouping;\r
+import eu.etaxonomy.cdm.persistence.query.MatchMode;\r
+import eu.etaxonomy.cdm.persistence.query.OrderHint;\r
+import eu.etaxonomy.cdm.persistence.query.OrderHint.SortOrder;\r
+import eu.etaxonomy.cdm.persistence.view.IAuditEventDao;\r
+import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest;\r
+\r
+/**\r
+ * @author a.mueller\r
+ * @author ben.clark\r
+ *\r
+ */\r
+public class AuditEventDaoTest extends CdmTransactionalIntegrationTest {\r
+       \r
+       @SpringBeanByType       \r
+       private IAuditEventDao auditEventDao;\r
+       \r
+       private DateTime dateTime;\r
+       \r
+       @Before\r
+       public void setUp() {\r
+               dateTime = new DateTime();\r
+       }\r
+       \r
+       \r
+       /**\r
+        * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.view.AuditEventDao#findByDate()}.\r
+        */\r
+       @Test\r
+       @DataSet\r
+       public void testFindByDate() {\r
+               AuditEvent auditEvent = auditEventDao.findByDate(dateTime);\r
+               assertNotNull(auditEvent);\r
+       }\r
+}\r
index 9a8cdd49fb55dc77506f45c531320663396e64fa..e4dd4f61938548eec734acf437bf51c826ba8c8f 100644 (file)
@@ -2082,8 +2082,7 @@ create table DefinedTermBase_MeasurementUnit (
         lsid_revision varchar(255),
         protectedtitlecache bit not null,
         titleCache varchar(255),
-        primary key (id),
-        unique (uuid)
+        primary key (id, REV)
     );
 
 
index 4a85b6318ba4c0e581d7c6fedb58a751f9047530..a2ef520e7f9e67a1422f065114a5869715343ebe 100644 (file)
@@ -1,5 +1,7 @@
 <?xml version='1.0' encoding='UTF-8'?>\r
 <dataset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../dataset.xsd">\r
+  <AUDITEVENT REVISIONNUMBER="1000" TIMESTAMP="1232914238974" UUID="a680fab4-365e-4765-b49e-768f2ee30cda"/>\r
+  <AUDITEVENT REVISIONNUMBER="1001" TIMESTAMP="1232914244116" UUID="afe8e761-8545-497b-9134-6a6791fc0b0d"/>\r
   <HOMOTYPICALGROUP ID="1" CREATED="2008-12-10 09:56:07.0" UUID="7b214eb9-a6ac-48e5-af02-bbea634d2a03" UPDATED="2008-12-10 09:56:07.238"/>\r
   <HOMOTYPICALGROUP ID="2" CREATED="2008-12-10 09:56:07.0" UUID="6c241a4c-e5a0-4344-8e5e-a81f17b75973" UPDATED="2008-12-10 09:56:07.253"/>\r
   <HOMOTYPICALGROUP_AUD ID="1" REV="1000" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="7b214eb9-a6ac-48e5-af02-bbea634d2a03" UPDATED="2008-12-10 09:56:07.238"/>\r
index 196d5eb0c5657877e5fc43cc0076376a544a4b7f..47f09782e777feb18d0ed6bbf4a75aa55eb2be21 100644 (file)
   <TAXONBASE DTYPE="Taxon" ID="38" CREATED="2008-12-10 09:56:07.0" UUID="bc09aca6-06fd-4905-b1e7-cbf7cc65d783" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Cryptocoryne x purpurea nothovar borneoensis N.Jacobsen, Bastm. &amp; Yuji Sasaki sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONSTATUSUNKNOWN="false" TAXONOMICCHILDRENCOUNT="0" TAXONNAME_FK="38" SEC_ID="3"/>
   <TAXONBASE_AUD DTYPE="Taxon" ID="1" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="496b1325-be50-4b0a-9aa2-3ecd610215f2" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE=" sec. ???" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="1" SEC_ID="1" TAXONOMICCHILDRENCOUNT="1" TAXONSTATUSUNKNOWN="false"/>
   <TAXONBASE_AUD DTYPE="Taxon" ID="2" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="822d98dc-9ef7-44b7-a870-94573a3bcb46" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="  sec. ???" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="2" SEC_ID="1" TAXONOMICCHILDRENCOUNT="0" TAXONOMICPARENTCACHE_ID="1" TAXONSTATUSUNKNOWN="false"/>
-  <TAXONBASE_AUD DTYPE="Taxon" ID="3" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="54e767ee-894e-4540-a758-f906ecb4e2d9" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Sphingidae Linnaeus, 1758 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="3" SEC_ID="2" TAXONOMICCHILDRENCOUNT="204" TAXONSTATUSUNKNOWN="false"/>
-  <TAXONBASE_AUD DTYPE="Taxon" ID="3" REV="1026" REVTYPE="1" CREATED="2008-12-10 09:56:07.0" UUID="54e767ee-894e-4540-a758-f906ecb4e2d9" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Sphingidae Linnaeus, 1758 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="3" SEC_ID="2" TAXONOMICCHILDRENCOUNT="204" TAXONSTATUSUNKNOWN="false"/>
+  <TAXONBASE_AUD DTYPE="Taxon" ID="3" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="54e767ee-894e-4540-a758-f906ecb4e2d9" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Sphingidae Linnaeus, 1758 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="3" SEC_ID="2" TAXONOMICCHILDRENCOUNT="204" TAXONSTATUSUNKNOWN="false" LSID_LSID="urn:lsid:cate-project.org:taxonconcepts:234" LSID_AUTHORITY="cate-project.org" LSID_NAMESPACE="taxonconcepts" LSID_OBJECT="234"/>
+  <TAXONBASE_AUD DTYPE="Taxon" ID="3" REV="1026" REVTYPE="1" CREATED="2008-12-10 09:56:07.0" UUID="54e767ee-894e-4540-a758-f906ecb4e2d9" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Sphingidae Linnaeus, 1758 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="3" SEC_ID="2" TAXONOMICCHILDRENCOUNT="204" TAXONSTATUSUNKNOWN="false" LSID_LSID="urn:lsid:cate-project.org:taxonconcepts:234" LSID_AUTHORITY="cate-project.org" LSID_NAMESPACE="taxonconcepts" LSID_OBJECT="234"/>
   <TAXONBASE_AUD DTYPE="Taxon" ID="4" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="ef96fafa-7750-4141-b31b-1ad1daab3e76" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Lathoe Fabricius, 1807 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="4" SEC_ID="2" TAXONOMICCHILDRENCOUNT="6" TAXONSTATUSUNKNOWN="false"/>
   <TAXONBASE_AUD DTYPE="Taxon" ID="5" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="17233b5e-74e7-42fc-bc37-522684657ed4" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Smerinthus Latreille, 1802 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="5" SEC_ID="2" TAXONOMICCHILDRENCOUNT="15" TAXONSTATUSUNKNOWN="false"/>
   <TAXONBASE_AUD DTYPE="Taxon" ID="6" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="b989a278-c414-49f7-9a10-7d784700e4c4" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Manduca Hübner, 1807 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="6" SEC_ID="2" TAXONOMICCHILDRENCOUNT="18" TAXONSTATUSUNKNOWN="false"/>
-  <TAXONBASE_AUD DTYPE="Taxon" ID="7" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="15611343-6b11-487f-8233-4756a49a83e2" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Lepchina Oberthür, 1904 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="7" SEC_ID="2" TAXONOMICCHILDRENCOUNT="13"/>
+  <TAXONBASE_AUD DTYPE="Taxon" ID="7" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="15611343-6b11-487f-8233-4756a49a83e2" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Lepchina Oberthür, 1904 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="7" SEC_ID="2" TAXONOMICCHILDRENCOUNT="13" TAXONSTATUSUNKNOWN="false"/>
   <TAXONBASE_AUD DTYPE="Taxon" ID="8" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="1489d3dd-71da-4b34-aa5a-d15fccb6bb22" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Smerinthus kindermannii Lederer, 1853 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="8" SEC_ID="2" TAXONOMICCHILDRENCOUNT="4" TAXONSTATUSUNKNOWN="false"/>
-  <TAXONBASE_AUD DTYPE="Taxon" ID="9" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="900052b7-b69c-4e26-a8f0-01c215214c40" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Mimas Hübner, 1819 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="9" SEC_ID="2" TAXONOMICCHILDRENCOUNT="2"/>
+  <TAXONBASE_AUD DTYPE="Taxon" ID="9" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="900052b7-b69c-4e26-a8f0-01c215214c40" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Mimas Hübner, 1819 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="9" SEC_ID="2" TAXONOMICCHILDRENCOUNT="2" TAXONSTATUSUNKNOWN="false"/>
   <TAXONBASE_AUD DTYPE="Taxon" ID="10" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="8e312b40-924f-46b7-8e8d-837f9ad12f51" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Callambulyx Rothschild &amp; Jordan, 1903 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="10" SEC_ID="2" TAXONOMICCHILDRENCOUNT="9" TAXONSTATUSUNKNOWN="false"/>
   <TAXONBASE_AUD DTYPE="Taxon" ID="11" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="53fac190-0b4b-44f5-b4e7-b1ca9a25a6e9" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Dolbina Staudinger, 1877 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="11" SEC_ID="2" TAXONOMICCHILDRENCOUNT="7" TAXONSTATUSUNKNOWN="false"/>
   <TAXONBASE_AUD DTYPE="Taxon" ID="12" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="7748d6f0-04d8-4052-9904-c43f55682419" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Akbesia Rothschild &amp; Jordan, 1903 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="12" SEC_ID="2" TAXONOMICCHILDRENCOUNT="1" TAXONSTATUSUNKNOWN="false"/>
   <TAXONBASE_AUD DTYPE="Taxon" ID="15" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="c5cc8674-4242-49a4-aada-72d63194f5fa" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Acherontia Laspeyres, 1809 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="15" SEC_ID="2" TAXONOMICCHILDRENCOUNT="3" TAXONSTATUSUNKNOWN="false"/>
   <TAXONBASE_AUD DTYPE="Taxon" ID="15" REV="1026" REVTYPE="2"/>
   <TAXONBASE_AUD DTYPE="Taxon" ID="16" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="6ecc117a-3e9a-4030-8748-f63a0412e065" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Hemaris Dalman, 1816 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="16" SEC_ID="2" TAXONOMICCHILDRENCOUNT="23" TAXONSTATUSUNKNOWN="false"/>
-  <TAXONBASE_AUD DTYPE="Taxon" ID="17" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="f6700b5b-b6dc-421a-b979-9429ffad8262" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Proserpinus Hübner, 1819 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="17" SEC_ID="2" TAXONOMICCHILDRENCOUNT="7"/>
+  <TAXONBASE_AUD DTYPE="Taxon" ID="17" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="f6700b5b-b6dc-421a-b979-9429ffad8262" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Proserpinus Hübner, 1819 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="17" SEC_ID="2" TAXONOMICCHILDRENCOUNT="7" TAXONSTATUSUNKNOWN="false"/>
   <TAXONBASE_AUD DTYPE="Taxon" ID="18" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="b503efaf-b800-421b-beba-3c6fab4b3c34" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Sphingonaepiopsis Wallengren, 1858 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="18" SEC_ID="2" TAXONOMICCHILDRENCOUNT="7" TAXONSTATUSUNKNOWN="false"/>
   <TAXONBASE_AUD DTYPE="Taxon" ID="19" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="a9f42927-e507-4fda-9629-62073a908aae" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Rethera Rothschild &amp; Jordan, 1903 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="19" SEC_ID="2" TAXONOMICCHILDRENCOUNT="4" TAXONSTATUSUNKNOWN="false"/>
   <TAXONBASE_AUD DTYPE="Taxon" ID="20" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="557ac748-90df-47a6-b6f4-92d7b1d53abb" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Daphnis Hübner, 1819 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="20" SEC_ID="2" TAXONOMICCHILDRENCOUNT="10" TAXONSTATUSUNKNOWN="false"/>
-  <TAXONBASE_AUD DTYPE="Taxon" ID="21" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="c089d514-f599-4f5a-bc90-3a11176d0f76" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Clarina Tutt, 1903 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="21" SEC_ID="2" TAXONOMICCHILDRENCOUNT="2"/>
+  <TAXONBASE_AUD DTYPE="Taxon" ID="21" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="c089d514-f599-4f5a-bc90-3a11176d0f76" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Clarina Tutt, 1903 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="21" SEC_ID="2" TAXONOMICCHILDRENCOUNT="2" TAXONSTATUSUNKNOWN="false"/>
   <TAXONBASE_AUD DTYPE="Taxon" ID="22" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="74ad1d5e-4f73-4e0d-a209-4bf07abd33fa" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Acosmeryx Boisduval, 1875 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="22" SEC_ID="2" TAXONOMICCHILDRENCOUNT="12" TAXONSTATUSUNKNOWN="false"/>
   <TAXONBASE_AUD DTYPE="Taxon" ID="23" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="8ecb0dfa-31fd-4f5a-bb83-b897cda813db" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Macroglossum Scopoli, 1777 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="23" SEC_ID="2" TAXONOMICCHILDRENCOUNT="104" TAXONSTATUSUNKNOWN="false"/>
   <TAXONBASE_AUD DTYPE="Taxon" ID="24" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="3d2a3441-4602-405f-8ba7-0685d88d7235" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Hyles Hübner, 1819 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="24" SEC_ID="2" TAXONOMICCHILDRENCOUNT="31" TAXONSTATUSUNKNOWN="false"/>
diff --git a/cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/view/AuditEventDaoTest.xml b/cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/view/AuditEventDaoTest.xml
new file mode 100644 (file)
index 0000000..423ee17
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<dataset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../dataset.xsd">
+  <AUDITEVENT REVISIONNUMBER="1025" TIMESTAMP="1232914238974" UUID="a680fab4-365e-4765-b49e-768f2ee30cda"/>
+  <AUDITEVENT REVISIONNUMBER="1026" TIMESTAMP="1232914244116" UUID="afe8e761-8545-497b-9134-6a6791fc0b0d"/>
+</dataset>