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 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<? extends RevisionListener> 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<? extends RevisionListener>) Thread.currentThread().getContextClassLoader().loadClass(revisionListenerClassName);
@ -164,4 +174,8 @@ public class GlobalConfiguration {
public boolean isUsingModifiedFlag() {
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) {
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)
*/
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) {

View File

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

View File

@ -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<AuditOverride> 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();

View File

@ -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

View File

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

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.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");

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