HHH-7918 - Fix and test
This commit is contained in:
parent
6062eb67ea
commit
2a9f3ad9ed
|
@ -427,7 +427,7 @@ public final class AuditMetadataGenerator {
|
|||
ExtendedPropertyMapper propertyMapper = null;
|
||||
String parentEntityName = null;
|
||||
EntityConfiguration entityCfg = new EntityConfiguration(entityName, pc.getClassName(), idMapper, propertyMapper,
|
||||
parentEntityName);
|
||||
parentEntityName, auditingData.isUsingModifiedFlag());
|
||||
notAuditedEntitiesConfigurations.put(entityName, entityCfg);
|
||||
return;
|
||||
}
|
||||
|
@ -501,7 +501,7 @@ public final class AuditMetadataGenerator {
|
|||
|
||||
// Storing the generated configuration
|
||||
EntityConfiguration entityCfg = new EntityConfiguration(auditEntityName, pc.getClassName(), idMapper,
|
||||
propertyMapper, parentEntityName);
|
||||
propertyMapper, parentEntityName, auditingData.isUsingModifiedFlag());
|
||||
entitiesConfigurations.put(pc.getEntityName(), entityCfg);
|
||||
}
|
||||
|
||||
|
|
|
@ -86,6 +86,18 @@ public class ClassAuditingData implements AuditedPropertiesHolder {
|
|||
return defaultAudited || properties.size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if any of the properties has modification flag enabled, {@code false} otherwise.
|
||||
*/
|
||||
public boolean isUsingModifiedFlag() {
|
||||
for ( PropertyAuditingData prop : properties.values() ) {
|
||||
if ( prop.isUsingModifiedFlag() ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean contains(String propertyName) {
|
||||
return properties.containsKey(propertyName);
|
||||
}
|
||||
|
|
|
@ -42,14 +42,16 @@ public class EntityConfiguration {
|
|||
// Maps from property name
|
||||
private Map<String, RelationDescription> relations;
|
||||
private String parentEntityName;
|
||||
private boolean usingModifiedFlag;
|
||||
|
||||
public EntityConfiguration(String versionsEntityName, String entityClassName, IdMappingData idMappingData,
|
||||
ExtendedPropertyMapper propertyMapper, String parentEntityName) {
|
||||
ExtendedPropertyMapper propertyMapper, String parentEntityName, boolean usingModifiedFlag) {
|
||||
this.versionsEntityName = versionsEntityName;
|
||||
this.entityClassName = entityClassName;
|
||||
this.idMappingData = idMappingData;
|
||||
this.propertyMapper = propertyMapper;
|
||||
this.parentEntityName = parentEntityName;
|
||||
this.usingModifiedFlag = usingModifiedFlag;
|
||||
|
||||
this.relations = new HashMap<String, RelationDescription>();
|
||||
}
|
||||
|
@ -123,4 +125,11 @@ public class EntityConfiguration {
|
|||
public String getEntityClassName() {
|
||||
return entityClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if the entity or any of its properties use modification flag, {@code false} otherwise.
|
||||
*/
|
||||
public boolean isUsingModifiedFlag() {
|
||||
return usingModifiedFlag;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,5 +72,4 @@ public interface PropertyMapper {
|
|||
|
||||
void mapModifiedFlagsToMapFromEntity(SessionImplementor session, Map<String, Object> data, Object newObj, Object oldObj);
|
||||
void mapModifiedFlagsToMapForCollectionChange(String collectionPropertyName, Map<String, Object> data);
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.envers.synchronization.work;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -38,10 +39,17 @@ public class ModWorkUnit extends AbstractAuditWorkUnit implements AuditWorkUnit
|
|||
private final Map<String, Object> data;
|
||||
private final boolean changes;
|
||||
|
||||
private final EntityPersister entityPersister;
|
||||
private final Object[] oldState;
|
||||
private final Object[] newState;
|
||||
|
||||
public ModWorkUnit(SessionImplementor sessionImplementor, String entityName, AuditConfiguration verCfg,
|
||||
Serializable id, EntityPersister entityPersister, Object[] newState, Object[] oldState) {
|
||||
super(sessionImplementor, entityName, verCfg, id, RevisionType.MOD);
|
||||
|
||||
this.entityPersister = entityPersister;
|
||||
this.oldState = oldState;
|
||||
this.newState = newState;
|
||||
data = new HashMap<String, Object>();
|
||||
changes = verCfg.getEntCfg().get(getEntityName()).getPropertyMapper().map(sessionImplementor, data,
|
||||
entityPersister.getPropertyNames(), newState, oldState);
|
||||
|
@ -66,6 +74,14 @@ public class ModWorkUnit extends AbstractAuditWorkUnit implements AuditWorkUnit
|
|||
}
|
||||
|
||||
public AuditWorkUnit merge(ModWorkUnit second) {
|
||||
if ( verCfg.getEntCfg().get( getEntityName() ).isUsingModifiedFlag() ) {
|
||||
// In case of multiple subsequent flushes within single transaction, modification flags need to be
|
||||
// recalculated against initial and final state of the given entity.
|
||||
return new ModWorkUnit(
|
||||
second.sessionImplementor, second.getEntityName(), second.verCfg, second.id,
|
||||
second.entityPersister, second.newState, this.oldState
|
||||
);
|
||||
}
|
||||
return second;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
package org.hibernate.envers.test.integration.modifiedflags;
|
||||
|
||||
import java.util.List;
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.envers.test.Priority;
|
||||
import org.hibernate.envers.test.integration.basic.BasicTestEntity1;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
|
||||
import static org.hibernate.envers.test.tools.TestTools.extractRevisionNumbers;
|
||||
import static org.hibernate.envers.test.tools.TestTools.makeList;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||
*/
|
||||
@TestForIssue(jiraKey = "HHH-7918")
|
||||
public class HasChangedManualFlush extends AbstractModifiedFlagsEntityTest {
|
||||
private Integer id = null;
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] { BasicTestEntity1.class };
|
||||
}
|
||||
|
||||
@Test
|
||||
@Priority(10)
|
||||
public void initData() {
|
||||
EntityManager em = getEntityManager();
|
||||
|
||||
// Revision 1
|
||||
em.getTransaction().begin();
|
||||
BasicTestEntity1 entity = new BasicTestEntity1( "str1", 1 );
|
||||
em.persist( entity );
|
||||
em.getTransaction().commit();
|
||||
|
||||
id = entity.getId();
|
||||
|
||||
// Revision 2 - both properties (str1 and long1) should be marked as modified.
|
||||
em.getTransaction().begin();
|
||||
entity = em.find( BasicTestEntity1.class, entity.getId() );
|
||||
entity.setStr1( "str2" );
|
||||
entity = em.merge( entity );
|
||||
em.flush();
|
||||
entity.setLong1( 2 );
|
||||
entity = em.merge( entity );
|
||||
em.flush();
|
||||
em.getTransaction().commit();
|
||||
|
||||
em.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasChangedOnDoubleFlush() {
|
||||
List list = queryForPropertyHasChanged( BasicTestEntity1.class, id, "str1" );
|
||||
assertEquals( 2, list.size() );
|
||||
assertEquals( makeList( 1, 2 ), extractRevisionNumbers( list ) );
|
||||
|
||||
list = queryForPropertyHasChanged( BasicTestEntity1.class, id, "long1" );
|
||||
assertEquals( 2, list.size() );
|
||||
assertEquals( makeList( 1, 2 ), extractRevisionNumbers( list ) );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue