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 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.mapping.SimpleValue;
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
if ( mapper != null ) {
mapper.add( propertyAuditingData.getPropertyData() );
final PropertyData propertyData = propertyAuditingData.resolvePropertyData( value.getType() );
mapper.add( propertyData );
}
return true;
@ -108,7 +110,8 @@ public final class BasicMetadataGenerator {
// A null mapper means that we only want to add xml mappings
if ( mapper != null ) {
mapper.add( propertyAuditingData.getPropertyData() );
final PropertyData propertyData = propertyAuditingData.resolvePropertyData( value.getType() );
mapper.add( propertyData );
}
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.
if ( positionMappedBy != null ) {
final Type indexType = ( (IndexedCollection) propertyValue ).getIndex().getType();
fakeBidirectionalRelationIndexMapper = new SinglePropertyMapper(
new PropertyData(
positionMappedBy,
null,
null,
null
)
PropertyData.forProperty( positionMappedBy, indexType )
);
// 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.internal.entities.PropertyData;
import org.hibernate.mapping.Value;
import org.hibernate.type.Type;
/**
* @author Adam Warski (adam at warski dot org)
@ -141,7 +142,12 @@ public class PropertyAuditingData {
this.accessType = accessType;
}
// todo (6.0) - remove this and use #resolvePropertyData instead
public PropertyData getPropertyData() {
return resolvePropertyData( null );
}
public PropertyData resolvePropertyData(Type propertyType) {
return new PropertyData(
name,
beanName,
@ -149,7 +155,8 @@ public class PropertyAuditingData {
store,
usingModifiedFlag,
modifiedFlagName,
syntheic
syntheic,
propertyType
);
}

View File

@ -8,6 +8,7 @@ package org.hibernate.envers.internal.entities;
import org.hibernate.envers.ModificationStore;
import org.hibernate.internal.util.compare.EqualsHelper;
import org.hibernate.type.Type;
/**
* 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.
// They're properties used for bookkeeping by Hibernate
private boolean synthetic;
private Type propertyType;
/**
* Copies the given property data, except the name.
@ -55,6 +57,11 @@ public class PropertyData {
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 beanName Name of the property in the bean.
@ -76,6 +83,19 @@ public class PropertyData {
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() {
return name;
}
@ -108,6 +128,10 @@ public class PropertyData {
return synthetic;
}
public Type getType() {
return propertyType;
}
@Override
public boolean equals(Object o) {
if ( this == o ) {
@ -136,4 +160,14 @@ public class PropertyData {
result = 31 * result + (synthetic ? 1 : 0);
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.
dbLogicallyDifferent = !(StringTools.isEmpty( newObj ) && StringTools.isEmpty( oldObj ));
}
return dbLogicallyDifferent && !EqualsHelper.areEqual( newObj, oldObj );
return dbLogicallyDifferent && !areEqual( newObj, oldObj );
}
@Override
@ -74,7 +74,7 @@ public class SinglePropertyMapper implements PropertyMapper, SimpleMapperBuilder
Object oldObj) {
// Synthetic properties are not subject to withModifiedFlag analysis
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() {
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 );
}
}