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

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Nov 25 11:32:05 EST 2009


Author: adamw
Date: 2009-11-25 11:32:05 -0500 (Wed, 25 Nov 2009)
New Revision: 18068

Added:
   core/trunk/envers/src/test/java/org/hibernate/envers/test/entities/reventity/CustomRevEntityColumnMapping.java
   core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/CustomColumnMapping.java
Modified:
   core/trunk/envers/pom.xml
   core/trunk/envers/src/main/java/org/hibernate/envers/configuration/RevisionInfoConfiguration.java
   core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java
   core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/MetadataTools.java
Log:
HHH-4611:
- handling the case when the revision number in the revision entity uses a @Column(columnDefinition=): the sql-type is property is then set on the REV property of audit entities

Modified: core/trunk/envers/pom.xml
===================================================================
--- core/trunk/envers/pom.xml	2009-11-25 15:24:24 UTC (rev 18067)
+++ core/trunk/envers/pom.xml	2009-11-25 16:32:05 UTC (rev 18068)
@@ -106,6 +106,12 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>5.1.10</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>cglib</groupId>
             <artifactId>cglib</artifactId>
             <scope>test</scope>

Modified: core/trunk/envers/src/main/java/org/hibernate/envers/configuration/RevisionInfoConfiguration.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/configuration/RevisionInfoConfiguration.java	2009-11-25 15:24:24 UTC (rev 18067)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/configuration/RevisionInfoConfiguration.java	2009-11-25 16:32:05 UTC (rev 18068)
@@ -49,6 +49,8 @@
 import org.hibernate.type.LongType;
 import org.hibernate.type.Type;
 
+import javax.persistence.Column;
+
 /**
  * @author Adam Warski (adam at warski dot org)
  */
@@ -59,6 +61,7 @@
     private Type revisionInfoTimestampType;
 
     private String revisionPropType;
+    private Column revisionPropColumn;
 
     public RevisionInfoConfiguration() {
         revisionInfoEntityName = "org.hibernate.envers.DefaultRevisionEntity";
@@ -90,10 +93,15 @@
 
     private Element generateRevisionInfoRelationMapping() {
         Document document = DocumentHelper.createDocument();
-        Element rev_rel_mapping =document.addElement("key-many-to-one");
+        Element rev_rel_mapping = document.addElement("key-many-to-one");
         rev_rel_mapping.addAttribute("type", revisionPropType);
         rev_rel_mapping.addAttribute("class", revisionInfoEntityName);
 
+        if (revisionPropColumn != null) {
+            // Putting a fake name to make Hibernate happy. It will be replaced later anyway.
+            MetadataTools.addColumn(rev_rel_mapping, "*" , null, 0, 0, revisionPropColumn.columnDefinition());
+        }
+
         return rev_rel_mapping;
     }
 
@@ -125,6 +133,11 @@
                     throw new MappingException("The field annotated with @RevisionNumber must be of type " +
                             "int, Integer, long or Long");
                 }
+
+                // Getting the @Column definition of the revision number property, to later use that info to
+                // generate the same mapping for the relation from an audit table's revision number to the
+                // revision entity revision number.
+                revisionPropColumn = property.getAnnotation(Column.class);
             }
 
             if (revisionTimestamp != null) {

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	2009-11-25 15:24:24 UTC (rev 18067)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java	2009-11-25 16:32:05 UTC (rev 18068)
@@ -40,7 +40,6 @@
 import org.hibernate.envers.entities.mapper.SubclassPropertyMapper;
 import org.hibernate.envers.tools.StringTools;
 import org.hibernate.envers.tools.Triple;
-import org.hibernate.envers.AuditTable;
 
 import org.hibernate.MappingException;
 import org.hibernate.cfg.Configuration;
@@ -90,8 +89,9 @@
     void addRevisionInfoRelation(Element any_mapping) {
         Element rev_mapping = (Element) revisionInfoRelationMapping.clone();
         rev_mapping.addAttribute("name", verEntCfg.getRevisionFieldName());
-        MetadataTools.addColumn(rev_mapping, verEntCfg.getRevisionFieldName(), null, 0, 0, null);
 
+        MetadataTools.addOrModifyColumn(rev_mapping, verEntCfg.getRevisionFieldName());
+
         any_mapping.add(rev_mapping);
     }
 

Modified: core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/MetadataTools.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/MetadataTools.java	2009-11-25 15:24:24 UTC (rev 18067)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/MetadataTools.java	2009-11-25 16:32:05 UTC (rev 18068)
@@ -68,6 +68,25 @@
         return prop_mapping;
     }
 
+    public static Element addOrModifyColumn(Element parent, String name) {
+        Element column_mapping = parent.element("column");
+
+        if (column_mapping == null) {
+            return addColumn(parent, name, null, 0, 0, null);
+        }
+
+        if (!StringTools.isEmpty(name)) {
+            Attribute nameAttribute = column_mapping.attribute("name");
+            if (nameAttribute == null) {
+                column_mapping.addAttribute("name", name);
+            } else {
+                nameAttribute.setValue(name);
+            }
+        }
+
+        return column_mapping;
+    }
+
     public static Element addColumn(Element parent, String name, Integer length, Integer scale, Integer precision,
 									String sqlType) {
         Element column_mapping = parent.addElement("column");
@@ -82,7 +101,7 @@
 		if (precision != 0) {
 			column_mapping.addAttribute("precision", Integer.toString(precision));
 		}
-		if (sqlType != null) {
+		if (!StringTools.isEmpty(sqlType)) {
             column_mapping.addAttribute("sql-type", sqlType);
         }
 

Copied: core/trunk/envers/src/test/java/org/hibernate/envers/test/entities/reventity/CustomRevEntityColumnMapping.java (from rev 18023, core/trunk/envers/src/test/java/org/hibernate/envers/test/entities/reventity/CustomRevEntity.java)
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/entities/reventity/CustomRevEntityColumnMapping.java	                        (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/entities/reventity/CustomRevEntityColumnMapping.java	2009-11-25 16:32:05 UTC (rev 18068)
@@ -0,0 +1,85 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.envers.test.entities.reventity;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Column;
+
+import org.hibernate.envers.RevisionEntity;
+import org.hibernate.envers.RevisionNumber;
+import org.hibernate.envers.RevisionTimestamp;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+ at Entity
+ at RevisionEntity
+public class CustomRevEntityColumnMapping {
+    @Id
+    @GeneratedValue
+    @Column(columnDefinition = "int")
+    @RevisionNumber
+    private Long customId;
+
+    @RevisionTimestamp
+    private long customTimestamp;
+
+    public Long getCustomId() {
+        return customId;
+    }
+
+    public void setCustomId(Long customId) {
+        this.customId = customId;
+    }
+
+    public long getCustomTimestamp() {
+        return customTimestamp;
+    }
+
+    public void setCustomTimestamp(long customTimestamp) {
+        this.customTimestamp = customTimestamp;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        CustomRevEntityColumnMapping that = (CustomRevEntityColumnMapping) o;
+
+        if (customTimestamp != that.customTimestamp) return false;
+        if (customId != null ? !customId.equals(that.customId) : that.customId != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = customId != null ? customId.hashCode() : 0;
+        result = 31 * result + (int) (customTimestamp ^ (customTimestamp >>> 32));
+        return result;
+    }
+}
\ No newline at end of file

Copied: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/CustomColumnMapping.java (from rev 18023, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/Custom.java)
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/CustomColumnMapping.java	                        (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/CustomColumnMapping.java	2009-11-25 16:32:05 UTC (rev 18068)
@@ -0,0 +1,137 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.envers.test.integration.reventity;
+
+import java.util.Arrays;
+import java.util.Date;
+import javax.persistence.EntityManager;
+
+import org.hibernate.envers.AuditReader;
+import org.hibernate.envers.exception.RevisionDoesNotExistException;
+import org.hibernate.envers.test.AbstractEntityTest;
+import org.hibernate.envers.test.entities.StrTestEntity;
+import org.hibernate.envers.test.entities.reventity.CustomRevEntityColumnMapping;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import org.hibernate.ejb.Ejb3Configuration;
+
+/**
+ * Test which checks if auditing when the revision number in the revision entity has a @Column annotation with
+ * a columnDefinition specified works.
+ * @author Adam Warski (adam at warski dot org)
+ */
+public class CustomColumnMapping extends AbstractEntityTest {
+    private Integer id;
+    private long timestamp1;
+    private long timestamp2;
+    private long timestamp3;
+
+    public void configure(Ejb3Configuration cfg) {
+        cfg.addAnnotatedClass(StrTestEntity.class);
+        cfg.addAnnotatedClass(CustomRevEntityColumnMapping.class);
+    }
+
+    @BeforeClass(dependsOnMethods = "init")
+    public void initData() throws InterruptedException {
+        timestamp1 = System.currentTimeMillis();
+
+        Thread.sleep(100);
+
+        // Revision 1
+        EntityManager em = getEntityManager();
+        em.getTransaction().begin();
+        StrTestEntity te = new StrTestEntity("x");
+        em.persist(te);
+        id = te.getId();
+        em.getTransaction().commit();
+
+        timestamp2 = System.currentTimeMillis();
+
+        Thread.sleep(100);
+
+        // Revision 2
+        em.getTransaction().begin();
+        te = em.find(StrTestEntity.class, id);
+        te.setStr("y");
+        em.getTransaction().commit();
+
+        timestamp3 = System.currentTimeMillis();
+    }
+
+    @Test(expectedExceptions = RevisionDoesNotExistException.class)
+    public void testTimestamps1() {
+        getAuditReader().getRevisionNumberForDate(new Date(timestamp1));
+    }
+
+    @Test
+    public void testTimestamps() {
+        assert getAuditReader().getRevisionNumberForDate(new Date(timestamp2)).intValue() == 1;
+        assert getAuditReader().getRevisionNumberForDate(new Date(timestamp3)).intValue() == 2;
+    }
+
+    @Test
+    public void testDatesForRevisions() {
+        AuditReader vr = getAuditReader();
+        assert vr.getRevisionNumberForDate(vr.getRevisionDate(1l)).intValue() == 1;
+        assert vr.getRevisionNumberForDate(vr.getRevisionDate(2l)).intValue() == 2;
+    }
+
+    @Test
+    public void testRevisionsForDates() {
+        AuditReader vr = getAuditReader();
+
+        assert vr.getRevisionDate(vr.getRevisionNumberForDate(new Date(timestamp2))).getTime() <= timestamp2;
+        assert vr.getRevisionDate(vr.getRevisionNumberForDate(new Date(timestamp2)).longValue()+1l).getTime() > timestamp2;
+
+        assert vr.getRevisionDate(vr.getRevisionNumberForDate(new Date(timestamp3))).getTime() <= timestamp3;
+    }
+
+    @Test
+    public void testFindRevision() {
+        AuditReader vr = getAuditReader();
+
+        long rev1Timestamp = vr.findRevision(CustomRevEntityColumnMapping.class, 1l).getCustomTimestamp();
+        assert rev1Timestamp > timestamp1;
+        assert rev1Timestamp <= timestamp2;
+
+        long rev2Timestamp = vr.findRevision(CustomRevEntityColumnMapping.class, 2l).getCustomTimestamp();
+        assert rev2Timestamp > timestamp2;
+        assert rev2Timestamp <= timestamp3;
+    }
+
+    @Test
+    public void testRevisionsCounts() {
+        assert Arrays.asList(1l, 2l).equals(getAuditReader().getRevisions(StrTestEntity.class, id));
+    }
+
+    @Test
+    public void testHistoryOfId1() {
+        StrTestEntity ver1 = new StrTestEntity("x", id);
+        StrTestEntity ver2 = new StrTestEntity("y", id);
+
+        assert getAuditReader().find(StrTestEntity.class, id, 1l).equals(ver1);
+        assert getAuditReader().find(StrTestEntity.class, id, 2l).equals(ver2);
+    }
+}
\ No newline at end of file



More information about the hibernate-commits mailing list