diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/AddWorkUnit.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/AddWorkUnit.java index a4eb3aa0bb..9a4d8d7d17 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/AddWorkUnit.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/AddWorkUnit.java @@ -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 mergeModifiedFlags(Map lhs, Map 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; + } }