HHH-8049 - Fix and test

This commit is contained in:
Lukasz Antoniak 2013-04-09 11:52:40 +02:00
parent 96aa4a6239
commit 802fcf7b4e
6 changed files with 266 additions and 13 deletions

View File

@ -329,28 +329,33 @@ public class AuditedPropertiesReader {
} }
} }
private void addFromComponentProperty(XProperty property, private void addFromComponentProperty(XProperty property, String accessType, Component propertyValue, Audited allClassAudited) {
String accessType, Component propertyValue, Audited allClassAudited) {
ComponentAuditingData componentData = new ComponentAuditingData(); ComponentAuditingData componentData = new ComponentAuditingData();
boolean isAudited = fillPropertyData(property, componentData, accessType, boolean isAudited = fillPropertyData( property, componentData, accessType, allClassAudited );
allClassAudited);
if ( propertyValue.isDynamic() ) {
if ( isAudited ) {
throw new MappingException(
"Audited dynamic-component properties are not supported. Consider applying @NotAudited annotation to "
+ propertyValue.getOwner().getEntityName() + "#" + property + "."
);
}
return;
}
PersistentPropertiesSource componentPropertiesSource = new ComponentPropertiesSource( PersistentPropertiesSource componentPropertiesSource = new ComponentPropertiesSource(
reflectionManager, propertyValue reflectionManager, propertyValue
); );
ComponentAuditedPropertiesReader audPropReader = new ComponentAuditedPropertiesReader( ComponentAuditedPropertiesReader audPropReader = new ComponentAuditedPropertiesReader(
ModificationStore.FULL, componentPropertiesSource, ModificationStore.FULL, componentPropertiesSource, componentData, globalCfg, reflectionManager,
componentData, globalCfg, reflectionManager, propertyNamePrefix propertyNamePrefix + MappingTools.createComponentPrefix( property.getName() )
+ MappingTools );
.createComponentPrefix(property.getName()));
audPropReader.read(); audPropReader.read();
if (isAudited) { if ( isAudited ) {
// Now we know that the property is audited // Now we know that the property is audited
auditedPropertiesHolder.addPropertyAuditingData(property.getName(), auditedPropertiesHolder.addPropertyAuditingData( property.getName(), componentData );
componentData);
} }
} }

View File

@ -0,0 +1,62 @@
package org.hibernate.envers.test.integration.components.dynamic;
import java.io.File;
import java.io.Serializable;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import junit.framework.Assert;
import org.junit.Test;
import org.hibernate.MappingException;
import org.hibernate.cfg.Configuration;
import org.hibernate.envers.Audited;
import org.hibernate.envers.configuration.EnversSettings;
import org.hibernate.envers.internal.tools.StringTools;
import org.hibernate.envers.test.AbstractEnversTest;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.testing.ServiceRegistryBuilder;
import org.hibernate.testing.TestForIssue;
/**
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
@TestForIssue( jiraKey = "HHH-8049" )
public class AuditedDynamicComponentTest extends AbstractEnversTest {
@Test
public void testAuditedDynamicComponentFailure() throws URISyntaxException {
final Configuration config = new Configuration();
final URL hbm = Thread.currentThread().getContextClassLoader().getResource( "mappings/dynamicComponents/mapAudited.hbm.xml" );
config.addFile( new File( hbm.toURI() ) );
final String auditStrategy = getAuditStrategy();
if ( !StringTools.isEmpty( auditStrategy ) ) {
config.setProperty( EnversSettings.AUDIT_STRATEGY, auditStrategy );
}
final ServiceRegistry serviceRegistry = ServiceRegistryBuilder.buildServiceRegistry( config.getProperties() );
try {
config.buildSessionFactory( serviceRegistry );
Assert.fail( "MappingException expected" );
}
catch ( MappingException e ) {
Assert.assertEquals(
"Audited dynamic-component properties are not supported. Consider applying @NotAudited annotation to "
+ AuditedDynamicMapComponent.class.getName() + "#customFields.",
e.getMessage()
);
}
finally {
ServiceRegistryBuilder.destroy( serviceRegistry );
}
}
@Audited
public static class AuditedDynamicMapComponent implements Serializable {
public long id;
public String note;
public Map<String, Object> customFields = new HashMap<String, Object>(); // Invalid audited dynamic-component.
}
}

View File

@ -0,0 +1,80 @@
package org.hibernate.envers.test.integration.components.dynamic;
import java.util.Arrays;
import junit.framework.Assert;
import org.junit.Test;
import org.hibernate.Session;
import org.hibernate.envers.test.BaseEnversFunctionalTestCase;
import org.hibernate.envers.test.Priority;
import org.hibernate.testing.TestForIssue;
/**
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
@TestForIssue( jiraKey = "HHH-8049" )
public class NotAuditedDynamicComponentTest extends BaseEnversFunctionalTestCase {
@Override
protected String[] getMappings() {
return new String[] { "mappings/dynamicComponents/mapNotAudited.hbm.xml" };
}
@Test
@Priority(10)
public void initData() {
Session session = openSession();
// Revision 1
session.getTransaction().begin();
NotAuditedDynamicMapComponent entity = new NotAuditedDynamicMapComponent( 1L, "static field value" );
entity.getCustomFields().put( "prop1", 13 );
entity.getCustomFields().put( "prop2", 0.1f );
session.save( entity );
session.getTransaction().commit();
// No revision
session.getTransaction().begin();
entity = (NotAuditedDynamicMapComponent) session.get( NotAuditedDynamicMapComponent.class, entity.getId() );
entity.getCustomFields().put( "prop1", 0 );
session.update( entity );
session.getTransaction().commit();
// Revision 2
session.getTransaction().begin();
entity = (NotAuditedDynamicMapComponent) session.get( NotAuditedDynamicMapComponent.class, entity.getId() );
entity.setNote( "updated note" );
session.update( entity );
session.getTransaction().commit();
// Revision 3
session.getTransaction().begin();
entity = (NotAuditedDynamicMapComponent) session.load( NotAuditedDynamicMapComponent.class, entity.getId() );
session.delete( entity );
session.getTransaction().commit();
session.close();
}
@Test
public void testRevisionsCounts() {
Assert.assertEquals( Arrays.asList( 1, 2, 3 ), getAuditReader().getRevisions( NotAuditedDynamicMapComponent.class, 1L ) );
}
@Test
public void testHistoryOfId1() {
// Revision 1
NotAuditedDynamicMapComponent entity = new NotAuditedDynamicMapComponent( 1L, "static field value" );
NotAuditedDynamicMapComponent ver1 = getAuditReader().find( NotAuditedDynamicMapComponent.class, entity.getId(), 1 );
Assert.assertEquals( entity, ver1 );
// Assume empty NotAuditedDynamicMapComponent#customFields map, because dynamic-component is not audited.
Assert.assertTrue( ver1.getCustomFields().isEmpty() );
// Revision 2
entity.setNote( "updated note" );
NotAuditedDynamicMapComponent ver2 = getAuditReader().find( NotAuditedDynamicMapComponent.class, entity.getId(), 2 );
Assert.assertEquals( entity, ver2 );
// Assume empty NotAuditedDynamicMapComponent#customFields map, because dynamic-component is not audited.
Assert.assertTrue( ver2.getCustomFields().isEmpty() );
}
}

View File

@ -0,0 +1,78 @@
package org.hibernate.envers.test.integration.components.dynamic;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.hibernate.envers.Audited;
import org.hibernate.envers.NotAudited;
/**
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
@Audited
public class NotAuditedDynamicMapComponent implements Serializable {
private long id;
private String note;
private Map<String, Object> customFields = new HashMap<String, Object>();
public NotAuditedDynamicMapComponent() {
}
public NotAuditedDynamicMapComponent(long id, String note) {
this.id = id;
this.note = note;
}
@Override
public boolean equals(Object o) {
if ( this == o ) return true;
if ( !( o instanceof NotAuditedDynamicMapComponent ) ) return false;
NotAuditedDynamicMapComponent that = (NotAuditedDynamicMapComponent) o;
if ( id != that.id ) return false;
if ( customFields != null ? !customFields.equals( that.customFields ) : that.customFields != null ) return false;
if ( note != null ? !note.equals( that.note ) : that.note != null ) return false;
return true;
}
@Override
public int hashCode() {
int result = (int) ( id ^ ( id >>> 32 ) );
result = 31 * result + ( note != null ? note.hashCode() : 0 );
result = 31 * result + ( customFields != null ? customFields.hashCode() : 0 );
return result;
}
@Override
public String toString() {
return "NotAuditedDynamicMapComponent(id = " + id + ", note = " + note + ", customFields = " + customFields + ")";
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
@NotAudited // Dynamic components are not supported for audition.
public Map<String, Object> getCustomFields() {
return customFields;
}
public void setCustomFields(Map<String, Object> customFields) {
this.customFields = customFields;
}
}

View File

@ -0,0 +1,14 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping default-lazy="false">
<class name="org.hibernate.envers.test.integration.components.dynamic.AuditedDynamicComponentTest$AuditedDynamicMapComponent">
<id name="id" type="long" column="id" access="field"/>
<property name="note" type="string" access="field"/>
<dynamic-component name="customFields" access="field">
<property name="prop1" type="integer"/>
<property name="prop2" type="float"/>
</dynamic-component>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,14 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping default-lazy="false">
<class name="org.hibernate.envers.test.integration.components.dynamic.NotAuditedDynamicMapComponent">
<id name="id" type="long" column="id"/>
<property name="note" type="string"/>
<dynamic-component name="customFields">
<property name="prop1" type="integer"/>
<property name="prop2" type="float"/>
</dynamic-component>
</class>
</hibernate-mapping>