HHH-8049 - Fix and test
This commit is contained in:
parent
96aa4a6239
commit
802fcf7b4e
|
@ -329,28 +329,33 @@ public class AuditedPropertiesReader {
|
|||
}
|
||||
}
|
||||
|
||||
private void addFromComponentProperty(XProperty property,
|
||||
String accessType, Component propertyValue, Audited allClassAudited) {
|
||||
|
||||
private void addFromComponentProperty(XProperty property, String accessType, Component propertyValue, Audited allClassAudited) {
|
||||
ComponentAuditingData componentData = new ComponentAuditingData();
|
||||
boolean isAudited = fillPropertyData(property, componentData, accessType,
|
||||
allClassAudited);
|
||||
boolean isAudited = fillPropertyData( property, componentData, accessType, 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(
|
||||
reflectionManager, propertyValue
|
||||
);
|
||||
|
||||
ComponentAuditedPropertiesReader audPropReader = new ComponentAuditedPropertiesReader(
|
||||
ModificationStore.FULL, componentPropertiesSource,
|
||||
componentData, globalCfg, reflectionManager, propertyNamePrefix
|
||||
+ MappingTools
|
||||
.createComponentPrefix(property.getName()));
|
||||
ModificationStore.FULL, componentPropertiesSource, componentData, globalCfg, reflectionManager,
|
||||
propertyNamePrefix + MappingTools.createComponentPrefix( property.getName() )
|
||||
);
|
||||
audPropReader.read();
|
||||
|
||||
if (isAudited) {
|
||||
if ( isAudited ) {
|
||||
// Now we know that the property is audited
|
||||
auditedPropertiesHolder.addPropertyAuditingData(property.getName(),
|
||||
componentData);
|
||||
auditedPropertiesHolder.addPropertyAuditingData( property.getName(), componentData );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
}
|
|
@ -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() );
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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>
|
Loading…
Reference in New Issue