HHH-6605 - Added Mod Flags suffix configurability

This commit is contained in:
Michal Skowronek 2011-10-03 22:15:39 +02:00
parent 43a602b100
commit 1c7532f875
10 changed files with 186 additions and 19 deletions

View File

@ -37,6 +37,8 @@ import static org.hibernate.envers.tools.Tools.getProperty;
*/ */
public class GlobalConfiguration { public class GlobalConfiguration {
public static final String USING_MODIFIED_FLAG_PROPERTY = "org.hibernate.envers.using_modified_flag"; 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 // Should a revision be generated when a not-owned relation field changes
private final boolean generateRevisionsForCollections; private final boolean generateRevisionsForCollections;
@ -57,10 +59,13 @@ public class GlobalConfiguration {
// Revision listener class name. // Revision listener class name.
private final Class<? extends RevisionListener> revisionListenerClass; private final Class<? extends RevisionListener> revisionListenerClass;
// Should Envers use modified property flags by default // Should Envers use modified property flags by default
private boolean usingModifiedFlag; private boolean usingModifiedFlag;
// Indicates that user defined global behavior for modified flags feature // Indicates that user defined global behavior for modified flags feature
private boolean hasSettingForUsingModifiedFlag; 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 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, USING_MODIFIED_FLAG_PROPERTY,
"false"); "false");
usingModifiedFlag = Boolean.parseBoolean(usingModifiedFlagStr); 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) { if (revisionListenerClassName != null) {
try { try {
revisionListenerClass = (Class<? extends RevisionListener>) Thread.currentThread().getContextClassLoader().loadClass(revisionListenerClassName); revisionListenerClass = (Class<? extends RevisionListener>) Thread.currentThread().getContextClassLoader().loadClass(revisionListenerClassName);
@ -164,4 +174,8 @@ public class GlobalConfiguration {
public boolean isUsingModifiedFlag() { public boolean isUsingModifiedFlag() {
return usingModifiedFlag; return usingModifiedFlag;
} }
public String getModifiedFlagSuffix() {
return modifiedFlagSuffix;
}
} }

View File

@ -210,7 +210,9 @@ public final class AuditMetadataGenerator {
private void addModifiedFlagIfNeeded(Element parent, PropertyAuditingData propertyAuditingData, boolean processModifiedFlag) { private void addModifiedFlagIfNeeded(Element parent, PropertyAuditingData propertyAuditingData, boolean processModifiedFlag) {
if (processModifiedFlag && propertyAuditingData.isUsingModifiedFlag()) { if (processModifiedFlag && propertyAuditingData.isUsingModifiedFlag()) {
MetadataTools.addModifiedFlagProperty(parent, propertyAuditingData.getName()); MetadataTools.addModifiedFlagProperty(parent,
propertyAuditingData.getName(),
globalCfg.getModifiedFlagSuffix());
} }
} }

View File

@ -39,7 +39,6 @@ import java.util.Iterator;
* @author Michal Skowronek (mskowr at o2 dot pl) * @author Michal Skowronek (mskowr at o2 dot pl)
*/ */
public class MetadataTools { public class MetadataTools {
public static final String MOD_SUFFIX = "_mod";
public static Element addNativelyGeneratedId(Element parent, String name, String type) { public static Element addNativelyGeneratedId(Element parent, String name, String type) {
Element id_mapping = parent.addElement("id"); Element id_mapping = parent.addElement("id");
@ -76,12 +75,12 @@ public class MetadataTools {
return addProperty(parent, name, type, insertable, false, key); return addProperty(parent, name, type, insertable, false, key);
} }
public static Element addModifiedFlagProperty(Element parent, String propertyName) { public static Element addModifiedFlagProperty(Element parent, String propertyName, String suffix) {
return addProperty(parent, getModifiedFlagPropertyName(propertyName), "boolean", true, false, false); return addProperty(parent, getModifiedFlagPropertyName(propertyName, suffix), "boolean", true, false, false);
} }
public static String getModifiedFlagPropertyName(String propertyName) { public static String getModifiedFlagPropertyName(String propertyName, String suffix) {
return propertyName + MOD_SUFFIX; return propertyName + suffix;
} }
private static void addOrModifyAttribute(Element parent, String name, String value) { private static void addOrModifyAttribute(Element parent, String name, String value) {

View File

@ -12,6 +12,7 @@ import org.hibernate.envers.Audited;
import org.hibernate.envers.ModificationStore; import org.hibernate.envers.ModificationStore;
import org.hibernate.envers.NotAudited; import org.hibernate.envers.NotAudited;
import org.hibernate.envers.configuration.GlobalConfiguration; import org.hibernate.envers.configuration.GlobalConfiguration;
import org.hibernate.envers.configuration.metadata.MetadataTools;
import org.hibernate.envers.tools.MappingTools; import org.hibernate.envers.tools.MappingTools;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
import org.hibernate.mapping.Property; import org.hibernate.mapping.Property;
@ -250,9 +251,12 @@ public class AuditedPropertiesReader {
if(!this.checkAudited(property, propertyData, allClassAudited)){ if(!this.checkAudited(property, propertyData, allClassAudited)){
return false; 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.setBeanName(property.getName());
propertyData.setAccessType(accessType); propertyData.setAccessType(accessType);

View File

@ -23,12 +23,14 @@
* *
*/ */
package org.hibernate.envers.configuration.metadata.reader; package org.hibernate.envers.configuration.metadata.reader;
import org.hibernate.envers.*;
import org.hibernate.envers.entities.PropertyData;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; 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) * @author Adam Warski (adam at warski dot org)
@ -47,6 +49,7 @@ public class PropertyAuditingData {
private String positionMappedBy; private String positionMappedBy;
private boolean forceInsertable; private boolean forceInsertable;
private boolean usingModifiedFlag; private boolean usingModifiedFlag;
private String modifiedFlagName;
public PropertyAuditingData() { public PropertyAuditingData() {
} }
@ -114,7 +117,8 @@ public class PropertyAuditingData {
} }
public PropertyData getPropertyData() { public PropertyData getPropertyData() {
return new PropertyData(name, beanName, accessType, store, usingModifiedFlag); return new PropertyData(name, beanName, accessType, store,
usingModifiedFlag, modifiedFlagName);
} }
public List<AuditOverride> getAuditingOverrides() { public List<AuditOverride> getAuditingOverrides() {
@ -153,6 +157,10 @@ public class PropertyAuditingData {
this.usingModifiedFlag = usingModifiedFlag; this.usingModifiedFlag = usingModifiedFlag;
} }
public void setModifiedFlagName(String modifiedFlagName) {
this.modifiedFlagName = modifiedFlagName;
}
public void addAuditingOverride(AuditOverride annotation) { public void addAuditingOverride(AuditOverride annotation) {
if (annotation != null) { if (annotation != null) {
String overrideName = annotation.name(); String overrideName = annotation.name();

View File

@ -23,7 +23,6 @@
*/ */
package org.hibernate.envers.entities; package org.hibernate.envers.entities;
import org.hibernate.envers.ModificationStore; import org.hibernate.envers.ModificationStore;
import org.hibernate.envers.configuration.metadata.MetadataTools;
import java.util.Map; import java.util.Map;
@ -40,6 +39,7 @@ public class PropertyData {
private final String accessType; private final String accessType;
private final ModificationStore store; private final ModificationStore store;
private boolean usingModifiedFlag; private boolean usingModifiedFlag;
private String modifiedFlagName;
/** /**
* Copies the given property data, except the name. * Copies the given property data, except the name.
@ -73,9 +73,10 @@ public class PropertyData {
* @param store How this property should be stored. * @param store How this property should be stored.
* @param usingModifiedFlag Defines if field changes should be tracked * @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(name, beanName, accessType, store);
this.usingModifiedFlag = usingModifiedFlag; this.usingModifiedFlag = usingModifiedFlag;
this.modifiedFlagName = modifiedFlagName;
} }
public String getName() { public String getName() {
@ -103,7 +104,7 @@ public class PropertyData {
} }
private String getModifiedFlagPropertyName() { private String getModifiedFlagPropertyName() {
return MetadataTools.getModifiedFlagPropertyName(name); return modifiedFlagName;
} }
@Override @Override

View File

@ -38,6 +38,8 @@ public class ModifiedFlagPropertyName implements PropertyNameGetter {
} }
public String get(AuditConfiguration auditCfg) { public String get(AuditConfiguration auditCfg) {
return MetadataTools.getModifiedFlagPropertyName(propertyNameGetter.get(auditCfg)); return MetadataTools
.getModifiedFlagPropertyName(propertyNameGetter.get(auditCfg),
auditCfg.getGlobalCfg().getModifiedFlagSuffix());
} }
} }

View File

@ -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.Component1;
import org.hibernate.envers.test.entities.components.Component2; import org.hibernate.envers.test.entities.components.Component2;
import org.hibernate.envers.test.entities.components.ComponentTestEntity; import org.hibernate.envers.test.entities.components.ComponentTestEntity;
import org.hibernate.envers.test.tools.TestTools;
import org.junit.Test; import org.junit.Test;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
@ -122,6 +123,13 @@ public class HasChangedComponents extends AbstractModifiedFlagsEntityTest {
id4 = cte4.getId(); 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) @Test(expected = QueryException.class)
public void testHasChangedNotAudited() throws Exception { public void testHasChangedNotAudited() throws Exception {
queryForPropertyHasChanged(ComponentTestEntity.class, id1, "comp2"); queryForPropertyHasChanged(ComponentTestEntity.class, id1, "comp2");

View File

@ -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));
}
}

View File

@ -24,11 +24,15 @@
package org.hibernate.envers.test.tools; package org.hibernate.envers.test.tools;
import org.hibernate.envers.DefaultRevisionEntity; 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.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -84,4 +88,25 @@ public class TestTools {
} }
return result; return result;
} }
public static Set<String> extractModProperties(
PersistentClass persistentClass) {
return extractModProperties(persistentClass,
GlobalConfiguration.DEFAULT_MODIFIED_FLAG_SUFFIX);
}
public static Set<String> extractModProperties(
PersistentClass persistentClass, String suffix) {
Set<String> result = new HashSet<String>();
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;
}
} }