HHH-11582 - Fix inconsistent modified flags behavior when same entity

persisted and merged within the same transaction.
This commit is contained in:
Chris Cranford 2017-03-22 13:50:04 -04:00
parent 10a29b48c3
commit f9c1e7e339
1 changed files with 28 additions and 1 deletions

View File

@ -13,6 +13,8 @@ import java.util.Map;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.envers.RevisionType;
import org.hibernate.envers.boot.internal.EnversService;
import org.hibernate.envers.internal.entities.PropertyData;
import org.hibernate.envers.internal.entities.mapper.ExtendedPropertyMapper;
import org.hibernate.envers.internal.tools.ArraysTools;
import org.hibernate.persister.entity.EntityPersister;
@ -79,7 +81,13 @@ public class AddWorkUnit extends AbstractAuditWorkUnit implements AuditWorkUnit
@Override
public AuditWorkUnit merge(ModWorkUnit second) {
return new AddWorkUnit( sessionImplementor, entityName, enversService, id, second.getData() );
return new AddWorkUnit(
sessionImplementor,
entityName,
enversService,
id,
mergeModifiedFlags( data, second.getData() )
);
}
@Override
@ -102,4 +110,23 @@ public class AddWorkUnit extends AbstractAuditWorkUnit implements AuditWorkUnit
public AuditWorkUnit dispatch(WorkUnitMergeVisitor first) {
return first.merge( this );
}
private Map<String, Object> mergeModifiedFlags(Map<String, Object> lhs, Map<String, Object> rhs) {
final ExtendedPropertyMapper mapper = enversService.getEntitiesConfigurations().get( getEntityName() ).getPropertyMapper();
// Designed to take any lhs modified flag values of true and merge those into the data set for the rhs
// This makes sure that when merging ModAuditWork with AddWorkUnit within the same transaction for the
// same entity that the modified flags are tracked correctly.
for ( PropertyData propertyData : mapper.getProperties().keySet() ) {
if ( propertyData.isUsingModifiedFlag() && !propertyData.isSynthetic() ) {
Boolean lhsValue = (Boolean) lhs.get( propertyData.getModifiedFlagPropertyName() );
if ( lhsValue != null && lhsValue ) {
Boolean rhsValue = (Boolean) rhs.get( propertyData.getModifiedFlagPropertyName() );
if ( rhsValue == null || !rhsValue ) {
rhs.put( propertyData.getModifiedFlagPropertyName(), true );
}
}
}
}
return rhs;
}
}