diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/GlobalConfiguration.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/GlobalConfiguration.java index 68902f1dcd..4f6003e7e5 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/GlobalConfiguration.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/GlobalConfiguration.java @@ -37,6 +37,8 @@ import static org.hibernate.envers.tools.Tools.getProperty; */ public class GlobalConfiguration { public static final String USING_MODIFIED_FLAG_PROPERTY = "org.hibernate.envers.using_modified_flag"; + public static final String MODIFIED_FLAG_SUFFIX_PROPERTY = "org.hibernate.envers.modified_flag_suffix"; + public static final String DEFAULT_MODIFIED_FLAG_SUFFIX = "_MOD"; // Should a revision be generated when a not-owned relation field changes private final boolean generateRevisionsForCollections; @@ -57,10 +59,13 @@ public class GlobalConfiguration { // Revision listener class name. private final Class revisionListenerClass; + // Should Envers use modified property flags by default private boolean usingModifiedFlag; // Indicates that user defined global behavior for modified flags feature private boolean hasSettingForUsingModifiedFlag; + // Suffix to be used for modified flags columns + private String modifiedFlagSuffix; /* Which operator to use in correlated subqueries (when we want a property to be equal to the result of @@ -108,8 +113,13 @@ public class GlobalConfiguration { USING_MODIFIED_FLAG_PROPERTY, "false"); usingModifiedFlag = Boolean.parseBoolean(usingModifiedFlagStr); - - String revisionListenerClassName = properties.getProperty("org.hibernate.envers.revision_listener", null); + + modifiedFlagSuffix = + getProperty(properties, MODIFIED_FLAG_SUFFIX_PROPERTY, + MODIFIED_FLAG_SUFFIX_PROPERTY, + DEFAULT_MODIFIED_FLAG_SUFFIX); + + String revisionListenerClassName = properties.getProperty("org.hibernate.envers.revision_listener", null); if (revisionListenerClassName != null) { try { revisionListenerClass = (Class) Thread.currentThread().getContextClassLoader().loadClass(revisionListenerClassName); @@ -164,4 +174,8 @@ public class GlobalConfiguration { public boolean isUsingModifiedFlag() { return usingModifiedFlag; } + + public String getModifiedFlagSuffix() { + return modifiedFlagSuffix; + } } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java index 9c93b7f38c..bc3eaa0fb7 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java @@ -210,7 +210,9 @@ public final class AuditMetadataGenerator { private void addModifiedFlagIfNeeded(Element parent, PropertyAuditingData propertyAuditingData, boolean processModifiedFlag) { if (processModifiedFlag && propertyAuditingData.isUsingModifiedFlag()) { - MetadataTools.addModifiedFlagProperty(parent, propertyAuditingData.getName()); + MetadataTools.addModifiedFlagProperty(parent, + propertyAuditingData.getName(), + globalCfg.getModifiedFlagSuffix()); } } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/MetadataTools.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/MetadataTools.java index e12f07e137..e67854547a 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/MetadataTools.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/MetadataTools.java @@ -39,7 +39,6 @@ import java.util.Iterator; * @author Michal Skowronek (mskowr at o2 dot pl) */ public class MetadataTools { - public static final String MOD_SUFFIX = "_mod"; public static Element addNativelyGeneratedId(Element parent, String name, String type) { Element id_mapping = parent.addElement("id"); @@ -76,12 +75,12 @@ public class MetadataTools { return addProperty(parent, name, type, insertable, false, key); } - public static Element addModifiedFlagProperty(Element parent, String propertyName) { - return addProperty(parent, getModifiedFlagPropertyName(propertyName), "boolean", true, false, false); + public static Element addModifiedFlagProperty(Element parent, String propertyName, String suffix) { + return addProperty(parent, getModifiedFlagPropertyName(propertyName, suffix), "boolean", true, false, false); } - public static String getModifiedFlagPropertyName(String propertyName) { - return propertyName + MOD_SUFFIX; + public static String getModifiedFlagPropertyName(String propertyName, String suffix) { + return propertyName + suffix; } private static void addOrModifyAttribute(Element parent, String name, String value) { diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java index d991ad98ad..a4b5756957 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java @@ -12,6 +12,7 @@ import org.hibernate.envers.Audited; import org.hibernate.envers.ModificationStore; import org.hibernate.envers.NotAudited; import org.hibernate.envers.configuration.GlobalConfiguration; +import org.hibernate.envers.configuration.metadata.MetadataTools; import org.hibernate.envers.tools.MappingTools; import org.hibernate.mapping.Component; import org.hibernate.mapping.Property; @@ -250,9 +251,12 @@ public class AuditedPropertiesReader { if(!this.checkAudited(property, propertyData, allClassAudited)){ return false; } - - propertyData.setName(propertyNamePrefix + property.getName()); + String propertyName = propertyNamePrefix + property.getName(); + propertyData.setName(propertyName); + propertyData.setModifiedFlagName(MetadataTools + .getModifiedFlagPropertyName(propertyName, + globalCfg.getModifiedFlagSuffix())); propertyData.setBeanName(property.getName()); propertyData.setAccessType(accessType); diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/PropertyAuditingData.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/PropertyAuditingData.java index 89753c619c..f7bc84d335 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/PropertyAuditingData.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/PropertyAuditingData.java @@ -23,12 +23,14 @@ * */ package org.hibernate.envers.configuration.metadata.reader; - -import org.hibernate.envers.*; -import org.hibernate.envers.entities.PropertyData; - import java.util.ArrayList; import java.util.List; +import org.hibernate.envers.AuditJoinTable; +import org.hibernate.envers.AuditOverride; +import org.hibernate.envers.AuditOverrides; +import org.hibernate.envers.ModificationStore; +import org.hibernate.envers.RelationTargetAuditMode; +import org.hibernate.envers.entities.PropertyData; /** * @author Adam Warski (adam at warski dot org) @@ -47,6 +49,7 @@ public class PropertyAuditingData { private String positionMappedBy; private boolean forceInsertable; private boolean usingModifiedFlag; + private String modifiedFlagName; public PropertyAuditingData() { } @@ -114,7 +117,8 @@ public class PropertyAuditingData { } public PropertyData getPropertyData() { - return new PropertyData(name, beanName, accessType, store, usingModifiedFlag); + return new PropertyData(name, beanName, accessType, store, + usingModifiedFlag, modifiedFlagName); } public List getAuditingOverrides() { @@ -153,6 +157,10 @@ public class PropertyAuditingData { this.usingModifiedFlag = usingModifiedFlag; } + public void setModifiedFlagName(String modifiedFlagName) { + this.modifiedFlagName = modifiedFlagName; + } + public void addAuditingOverride(AuditOverride annotation) { if (annotation != null) { String overrideName = annotation.name(); diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/PropertyData.java b/hibernate-envers/src/main/java/org/hibernate/envers/entities/PropertyData.java index a38c5c7bd2..df1f42182a 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/PropertyData.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/entities/PropertyData.java @@ -23,7 +23,6 @@ */ package org.hibernate.envers.entities; import org.hibernate.envers.ModificationStore; -import org.hibernate.envers.configuration.metadata.MetadataTools; import java.util.Map; @@ -40,6 +39,7 @@ public class PropertyData { private final String accessType; private final ModificationStore store; private boolean usingModifiedFlag; + private String modifiedFlagName; /** * Copies the given property data, except the name. @@ -73,9 +73,10 @@ public class PropertyData { * @param store How this property should be stored. * @param usingModifiedFlag Defines if field changes should be tracked */ - public PropertyData(String name, String beanName, String accessType, ModificationStore store, boolean usingModifiedFlag) { + public PropertyData(String name, String beanName, String accessType, ModificationStore store, boolean usingModifiedFlag, String modifiedFlagName) { this(name, beanName, accessType, store); this.usingModifiedFlag = usingModifiedFlag; + this.modifiedFlagName = modifiedFlagName; } public String getName() { @@ -103,7 +104,7 @@ public class PropertyData { } private String getModifiedFlagPropertyName() { - return MetadataTools.getModifiedFlagPropertyName(name); + return modifiedFlagName; } @Override diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/property/ModifiedFlagPropertyName.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/property/ModifiedFlagPropertyName.java index d6f468d5fb..5e2750a828 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/property/ModifiedFlagPropertyName.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/property/ModifiedFlagPropertyName.java @@ -38,6 +38,8 @@ public class ModifiedFlagPropertyName implements PropertyNameGetter { } public String get(AuditConfiguration auditCfg) { - return MetadataTools.getModifiedFlagPropertyName(propertyNameGetter.get(auditCfg)); + return MetadataTools + .getModifiedFlagPropertyName(propertyNameGetter.get(auditCfg), + auditCfg.getGlobalCfg().getModifiedFlagSuffix()); } } diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/HasChangedComponents.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/HasChangedComponents.java index 3bd51f59f4..101e4680eb 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/HasChangedComponents.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/HasChangedComponents.java @@ -29,6 +29,7 @@ import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.components.Component1; import org.hibernate.envers.test.entities.components.Component2; import org.hibernate.envers.test.entities.components.ComponentTestEntity; +import org.hibernate.envers.test.tools.TestTools; import org.junit.Test; import javax.persistence.EntityManager; @@ -122,6 +123,13 @@ public class HasChangedComponents extends AbstractModifiedFlagsEntityTest { id4 = cte4.getId(); } + @Test + public void testModFlagProperties() { + assertEquals(TestTools.makeSet("comp1_MOD"), + TestTools.extractModProperties(getCfg().getClassMapping( + "org.hibernate.envers.test.entities.components.ComponentTestEntity_AUD"))); + } + @Test(expected = QueryException.class) public void testHasChangedNotAudited() throws Exception { queryForPropertyHasChanged(ComponentTestEntity.class, id1, "comp2"); diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/ModifiedFlagSuffix.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/ModifiedFlagSuffix.java new file mode 100644 index 0000000000..4e1d329fd3 --- /dev/null +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/ModifiedFlagSuffix.java @@ -0,0 +1,104 @@ +/* + * 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.modifiedflags; + +import org.hibernate.ejb.Ejb3Configuration; +import org.hibernate.envers.configuration.GlobalConfiguration; +import org.hibernate.envers.query.AuditEntity; +import org.hibernate.envers.test.Priority; +import org.hibernate.envers.test.integration.basic.BasicTestEntity1; +import org.hibernate.envers.test.tools.TestTools; +import org.junit.Test; + +import javax.persistence.EntityManager; +import java.util.List; +import java.util.Properties; + +import static junit.framework.Assert.assertEquals; +import static org.hibernate.envers.test.tools.TestTools.extractRevisionNumbers; +import static org.hibernate.envers.test.tools.TestTools.makeList; + +/** + * @author Adam Warski (adam at warski dot org) + * @author Michal Skowronek (mskowr at o2 dot pl) + */ +public class ModifiedFlagSuffix extends AbstractModifiedFlagsEntityTest { + private Integer id1; + + public void configure(Ejb3Configuration cfg) { + cfg.addAnnotatedClass(BasicTestEntity1.class); + } + + @Override + public void addConfigurationProperties(Properties configuration) { + super.addConfigurationProperties(configuration); + configuration + .setProperty(GlobalConfiguration.MODIFIED_FLAG_SUFFIX_PROPERTY, + "_CHANGED"); + } + + private Integer addNewEntity(String str, long lng) { + EntityManager em = getEntityManager(); + em.getTransaction().begin(); + BasicTestEntity1 bte1 = new BasicTestEntity1(str, lng); + em.persist(bte1); + em.getTransaction().commit(); + + return bte1.getId(); + } + + @Test + @Priority(10) + public void initData() { + id1 = addNewEntity("x", 1); // rev 1 + } + + @Test + public void testModFlagProperties() { + assertEquals(TestTools.makeSet("str1_CHANGED", "long1_CHANGED"), + TestTools.extractModProperties(getCfg().getClassMapping( + "org.hibernate.envers.test.integration.basic.BasicTestEntity1_AUD"), + "_CHANGED")); + } + + @Test + public void testHasChanged() throws Exception { + List list = queryForPropertyHasChangedWithDeleted(BasicTestEntity1.class, + id1, "str1"); + assertEquals(1, list.size()); + assertEquals(makeList(1), extractRevisionNumbers(list)); + + list = queryForPropertyHasChangedWithDeleted(BasicTestEntity1.class, + id1, "long1"); + assertEquals(1, list.size()); + assertEquals(makeList(1), extractRevisionNumbers(list)); + + list = getAuditReader().createQuery().forRevisionsOfEntity(BasicTestEntity1.class, false, true) + .add(AuditEntity.property("str1").hasChanged()) + .add(AuditEntity.property("long1").hasChanged()) + .getResultList(); + assertEquals(1, list.size()); + assertEquals(makeList(1), extractRevisionNumbers(list)); + } +} \ No newline at end of file diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/tools/TestTools.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/tools/TestTools.java index 1df1b19492..eef0b4bb16 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/tools/TestTools.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/tools/TestTools.java @@ -24,11 +24,15 @@ package org.hibernate.envers.test.tools; import org.hibernate.envers.DefaultRevisionEntity; +import org.hibernate.envers.configuration.GlobalConfiguration; +import org.hibernate.mapping.PersistentClass; +import org.hibernate.mapping.Property; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -84,4 +88,25 @@ public class TestTools { } return result; } + + public static Set extractModProperties( + PersistentClass persistentClass) { + return extractModProperties(persistentClass, + GlobalConfiguration.DEFAULT_MODIFIED_FLAG_SUFFIX); + } + + public static Set extractModProperties( + PersistentClass persistentClass, String suffix) { + Set result = new HashSet(); + Iterator iterator = persistentClass.getPropertyIterator(); + + while (iterator.hasNext()) { + Property property = (Property) iterator.next(); + String propertyName = property.getName(); + if (propertyName.endsWith(suffix)) { + result.add(propertyName); + } + } + return result; + } }