HHH-11988 - Avoid adding unnecessary audit rows for basic types.

This commit is contained in:
Chris Cranford 2017-10-17 13:54:09 -04:00
parent 4883e99818
commit aba202c71a
5 changed files with 63 additions and 11 deletions

View File

@ -9,6 +9,7 @@ package org.hibernate.envers.configuration.internal.metadata;
import java.util.Properties; import java.util.Properties;
import org.hibernate.envers.configuration.internal.metadata.reader.PropertyAuditingData; import org.hibernate.envers.configuration.internal.metadata.reader.PropertyAuditingData;
import org.hibernate.envers.internal.entities.PropertyData;
import org.hibernate.envers.internal.entities.mapper.SimpleMapperBuilder; import org.hibernate.envers.internal.entities.mapper.SimpleMapperBuilder;
import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Value; import org.hibernate.mapping.Value;
@ -52,7 +53,8 @@ public final class BasicMetadataGenerator {
// A null mapper means that we only want to add xml mappings // A null mapper means that we only want to add xml mappings
if ( mapper != null ) { if ( mapper != null ) {
mapper.add( propertyAuditingData.getPropertyData() ); final PropertyData propertyData = propertyAuditingData.resolvePropertyData( value.getType() );
mapper.add( propertyData );
} }
return true; return true;
@ -108,7 +110,8 @@ public final class BasicMetadataGenerator {
// A null mapper means that we only want to add xml mappings // A null mapper means that we only want to add xml mappings
if ( mapper != null ) { if ( mapper != null ) {
mapper.add( propertyAuditingData.getPropertyData() ); final PropertyData propertyData = propertyAuditingData.resolvePropertyData( value.getType() );
mapper.add( propertyData );
} }
return true; return true;

View File

@ -287,13 +287,9 @@ public final class CollectionMetadataGenerator {
// Checking if there's an index defined. If so, adding a mapper for it. // Checking if there's an index defined. If so, adding a mapper for it.
if ( positionMappedBy != null ) { if ( positionMappedBy != null ) {
final Type indexType = ( (IndexedCollection) propertyValue ).getIndex().getType();
fakeBidirectionalRelationIndexMapper = new SinglePropertyMapper( fakeBidirectionalRelationIndexMapper = new SinglePropertyMapper(
new PropertyData( PropertyData.forProperty( positionMappedBy, indexType )
positionMappedBy,
null,
null,
null
)
); );
// Also, overwriting the index component data to properly read the index. // Also, overwriting the index component data to properly read the index.

View File

@ -16,6 +16,7 @@ import org.hibernate.envers.ModificationStore;
import org.hibernate.envers.RelationTargetAuditMode; import org.hibernate.envers.RelationTargetAuditMode;
import org.hibernate.envers.internal.entities.PropertyData; import org.hibernate.envers.internal.entities.PropertyData;
import org.hibernate.mapping.Value; import org.hibernate.mapping.Value;
import org.hibernate.type.Type;
/** /**
* @author Adam Warski (adam at warski dot org) * @author Adam Warski (adam at warski dot org)
@ -141,7 +142,12 @@ public class PropertyAuditingData {
this.accessType = accessType; this.accessType = accessType;
} }
// todo (6.0) - remove this and use #resolvePropertyData instead
public PropertyData getPropertyData() { public PropertyData getPropertyData() {
return resolvePropertyData( null );
}
public PropertyData resolvePropertyData(Type propertyType) {
return new PropertyData( return new PropertyData(
name, name,
beanName, beanName,
@ -149,7 +155,8 @@ public class PropertyAuditingData {
store, store,
usingModifiedFlag, usingModifiedFlag,
modifiedFlagName, modifiedFlagName,
syntheic syntheic,
propertyType
); );
} }

View File

@ -8,6 +8,7 @@ package org.hibernate.envers.internal.entities;
import org.hibernate.envers.ModificationStore; import org.hibernate.envers.ModificationStore;
import org.hibernate.internal.util.compare.EqualsHelper; import org.hibernate.internal.util.compare.EqualsHelper;
import org.hibernate.type.Type;
/** /**
* Holds information on a property that is audited. * Holds information on a property that is audited.
@ -28,6 +29,7 @@ public class PropertyData {
// Synthetic properties are ones which are not part of the actual java model. // Synthetic properties are ones which are not part of the actual java model.
// They're properties used for bookkeeping by Hibernate // They're properties used for bookkeeping by Hibernate
private boolean synthetic; private boolean synthetic;
private Type propertyType;
/** /**
* Copies the given property data, except the name. * Copies the given property data, except the name.
@ -55,6 +57,11 @@ public class PropertyData {
this.store = store; this.store = store;
} }
private PropertyData(String name, String beanName, String accessType, ModificationStore store, Type propertyType) {
this( name, beanName, accessType, store );
this.propertyType = propertyType;
}
/** /**
* @param name Name of the property. * @param name Name of the property.
* @param beanName Name of the property in the bean. * @param beanName Name of the property in the bean.
@ -76,6 +83,19 @@ public class PropertyData {
this.synthetic = synthetic; this.synthetic = synthetic;
} }
public PropertyData(
String name,
String beanName,
String accessType,
ModificationStore store,
boolean usingModifiedFlag,
String modifiedFlagName,
boolean synthetic,
Type propertyType) {
this( name, beanName, accessType, store, usingModifiedFlag, modifiedFlagName, synthetic );
this.propertyType = propertyType;
}
public String getName() { public String getName() {
return name; return name;
} }
@ -108,6 +128,10 @@ public class PropertyData {
return synthetic; return synthetic;
} }
public Type getType() {
return propertyType;
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if ( this == o ) { if ( this == o ) {
@ -136,4 +160,14 @@ public class PropertyData {
result = 31 * result + (synthetic ? 1 : 0); result = 31 * result + (synthetic ? 1 : 0);
return result; return result;
} }
public static PropertyData forProperty(String propertyName, Type propertyType) {
return new PropertyData(
propertyName,
null,
null,
null,
propertyType
);
}
} }

View File

@ -63,7 +63,7 @@ public class SinglePropertyMapper implements PropertyMapper, SimpleMapperBuilder
// Don't generate new revision when database replaces empty string with NULL during INSERT or UPDATE statements. // Don't generate new revision when database replaces empty string with NULL during INSERT or UPDATE statements.
dbLogicallyDifferent = !(StringTools.isEmpty( newObj ) && StringTools.isEmpty( oldObj )); dbLogicallyDifferent = !(StringTools.isEmpty( newObj ) && StringTools.isEmpty( oldObj ));
} }
return dbLogicallyDifferent && !EqualsHelper.areEqual( newObj, oldObj ); return dbLogicallyDifferent && !areEqual( newObj, oldObj );
} }
@Override @Override
@ -74,7 +74,7 @@ public class SinglePropertyMapper implements PropertyMapper, SimpleMapperBuilder
Object oldObj) { Object oldObj) {
// Synthetic properties are not subject to withModifiedFlag analysis // Synthetic properties are not subject to withModifiedFlag analysis
if ( propertyData.isUsingModifiedFlag() && !propertyData.isSynthetic() ) { if ( propertyData.isUsingModifiedFlag() && !propertyData.isSynthetic() ) {
data.put( propertyData.getModifiedFlagPropertyName(), !EqualsHelper.areEqual( newObj, oldObj ) ); data.put( propertyData.getModifiedFlagPropertyName(), !areEqual( newObj, oldObj ) );
} }
} }
@ -137,4 +137,16 @@ public class SinglePropertyMapper implements PropertyMapper, SimpleMapperBuilder
public boolean hasPropertiesWithModifiedFlag() { public boolean hasPropertiesWithModifiedFlag() {
return propertyData != null && propertyData.isUsingModifiedFlag(); return propertyData != null && propertyData.isUsingModifiedFlag();
} }
private boolean areEqual(Object newObj, Object oldObj) {
// Should a Type have been specified on the property mapper, delegate there to make sure
// that proper equality comparison occurs based on the Type's semantics rather than the
// generalized EqualsHelper #areEqual call.
if ( propertyData.getType() != null ) {
return propertyData.getType().isEqual( newObj, oldObj );
}
// todo (6.0) - Confirm if this is still necessary as everything should use a JavaTypeDescriptor.
// This was maintained for legacy 5.2 behavior only.
return EqualsHelper.areEqual( newObj, oldObj );
}
} }