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;
|
ExtendedPropertyMapper propertyMapper = null;
|
||||||
String parentEntityName = null;
|
String parentEntityName = null;
|
||||||
EntityConfiguration entityCfg = new EntityConfiguration(entityName, pc.getClassName(), idMapper, propertyMapper,
|
EntityConfiguration entityCfg = new EntityConfiguration(entityName, pc.getClassName(), idMapper, propertyMapper,
|
||||||
parentEntityName);
|
parentEntityName, auditingData.isUsingModifiedFlag());
|
||||||
notAuditedEntitiesConfigurations.put(entityName, entityCfg);
|
notAuditedEntitiesConfigurations.put(entityName, entityCfg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -501,7 +501,7 @@ public final class AuditMetadataGenerator {
|
||||||
|
|
||||||
// Storing the generated configuration
|
// Storing the generated configuration
|
||||||
EntityConfiguration entityCfg = new EntityConfiguration(auditEntityName, pc.getClassName(), idMapper,
|
EntityConfiguration entityCfg = new EntityConfiguration(auditEntityName, pc.getClassName(), idMapper,
|
||||||
propertyMapper, parentEntityName);
|
propertyMapper, parentEntityName, auditingData.isUsingModifiedFlag());
|
||||||
entitiesConfigurations.put(pc.getEntityName(), entityCfg);
|
entitiesConfigurations.put(pc.getEntityName(), entityCfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,18 @@ public class ClassAuditingData implements AuditedPropertiesHolder {
|
||||||
return defaultAudited || properties.size() > 0;
|
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) {
|
public boolean contains(String propertyName) {
|
||||||
return properties.containsKey(propertyName);
|
return properties.containsKey(propertyName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,14 +42,16 @@ public class EntityConfiguration {
|
||||||
// Maps from property name
|
// Maps from property name
|
||||||
private Map<String, RelationDescription> relations;
|
private Map<String, RelationDescription> relations;
|
||||||
private String parentEntityName;
|
private String parentEntityName;
|
||||||
|
private boolean usingModifiedFlag;
|
||||||
|
|
||||||
public EntityConfiguration(String versionsEntityName, String entityClassName, IdMappingData idMappingData,
|
public EntityConfiguration(String versionsEntityName, String entityClassName, IdMappingData idMappingData,
|
||||||
ExtendedPropertyMapper propertyMapper, String parentEntityName) {
|
ExtendedPropertyMapper propertyMapper, String parentEntityName, boolean usingModifiedFlag) {
|
||||||
this.versionsEntityName = versionsEntityName;
|
this.versionsEntityName = versionsEntityName;
|
||||||
this.entityClassName = entityClassName;
|
this.entityClassName = entityClassName;
|
||||||
this.idMappingData = idMappingData;
|
this.idMappingData = idMappingData;
|
||||||
this.propertyMapper = propertyMapper;
|
this.propertyMapper = propertyMapper;
|
||||||
this.parentEntityName = parentEntityName;
|
this.parentEntityName = parentEntityName;
|
||||||
|
this.usingModifiedFlag = usingModifiedFlag;
|
||||||
|
|
||||||
this.relations = new HashMap<String, RelationDescription>();
|
this.relations = new HashMap<String, RelationDescription>();
|
||||||
}
|
}
|
||||||
|
@ -123,4 +125,11 @@ public class EntityConfiguration {
|
||||||
public String getEntityClassName() {
|
public String getEntityClassName() {
|
||||||
return entityClassName;
|
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 mapModifiedFlagsToMapFromEntity(SessionImplementor session, Map<String, Object> data, Object newObj, Object oldObj);
|
||||||
void mapModifiedFlagsToMapForCollectionChange(String collectionPropertyName, Map<String, Object> data);
|
void mapModifiedFlagsToMapForCollectionChange(String collectionPropertyName, Map<String, Object> data);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.envers.synchronization.work;
|
package org.hibernate.envers.synchronization.work;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -38,10 +39,17 @@ public class ModWorkUnit extends AbstractAuditWorkUnit implements AuditWorkUnit
|
||||||
private final Map<String, Object> data;
|
private final Map<String, Object> data;
|
||||||
private final boolean changes;
|
private final boolean changes;
|
||||||
|
|
||||||
|
private final EntityPersister entityPersister;
|
||||||
|
private final Object[] oldState;
|
||||||
|
private final Object[] newState;
|
||||||
|
|
||||||
public ModWorkUnit(SessionImplementor sessionImplementor, String entityName, AuditConfiguration verCfg,
|
public ModWorkUnit(SessionImplementor sessionImplementor, String entityName, AuditConfiguration verCfg,
|
||||||
Serializable id, EntityPersister entityPersister, Object[] newState, Object[] oldState) {
|
Serializable id, EntityPersister entityPersister, Object[] newState, Object[] oldState) {
|
||||||
super(sessionImplementor, entityName, verCfg, id, RevisionType.MOD);
|
super(sessionImplementor, entityName, verCfg, id, RevisionType.MOD);
|
||||||
|
|
||||||
|
this.entityPersister = entityPersister;
|
||||||
|
this.oldState = oldState;
|
||||||
|
this.newState = newState;
|
||||||
data = new HashMap<String, Object>();
|
data = new HashMap<String, Object>();
|
||||||
changes = verCfg.getEntCfg().get(getEntityName()).getPropertyMapper().map(sessionImplementor, data,
|
changes = verCfg.getEntCfg().get(getEntityName()).getPropertyMapper().map(sessionImplementor, data,
|
||||||
entityPersister.getPropertyNames(), newState, oldState);
|
entityPersister.getPropertyNames(), newState, oldState);
|
||||||
|
@ -66,6 +74,14 @@ public class ModWorkUnit extends AbstractAuditWorkUnit implements AuditWorkUnit
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuditWorkUnit merge(ModWorkUnit second) {
|
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;
|
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