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,
|
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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