HHH-6605 - Added Mod Flags suffix configurability
This commit is contained in:
parent
43a602b100
commit
1c7532f875
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue