HHH-8769 gracefully handle the lack of dynamic mode support in Envers

This commit is contained in:
Brett Meyer 2015-03-22 00:49:08 -04:00
parent 8d3d259963
commit bea160a7ad
3 changed files with 94 additions and 94 deletions

View File

@ -23,14 +23,12 @@
*/ */
package org.hibernate.envers.configuration.internal; package org.hibernate.envers.configuration.internal;
import java.io.ByteArrayOutputStream; import org.dom4j.Document;
import java.io.IOException; import org.dom4j.DocumentException;
import java.io.PrintWriter; import org.dom4j.Element;
import java.io.Writer; import org.dom4j.io.DOMWriter;
import java.util.HashMap; import org.dom4j.io.OutputFormat;
import java.util.Iterator; import org.dom4j.io.XMLWriter;
import java.util.Map;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.annotations.common.reflection.ReflectionManager; import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
@ -46,12 +44,13 @@ import org.hibernate.envers.internal.tools.graph.GraphTopologicalSort;
import org.hibernate.envers.strategy.AuditStrategy; import org.hibernate.envers.strategy.AuditStrategy;
import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.PersistentClass;
import org.dom4j.Document; import java.io.ByteArrayOutputStream;
import org.dom4j.DocumentException; import java.io.IOException;
import org.dom4j.Element; import java.io.PrintWriter;
import org.dom4j.io.DOMWriter; import java.io.Writer;
import org.dom4j.io.OutputFormat; import java.util.HashMap;
import org.dom4j.io.XMLWriter; import java.util.Iterator;
import java.util.Map;
/** /**
* @author Adam Warski (adam at warski dot org) * @author Adam Warski (adam at warski dot org)
@ -77,12 +76,15 @@ public class EntitiesConfigurator {
while ( classes.hasNext() ) { while ( classes.hasNext() ) {
final PersistentClass pc = classes.next(); final PersistentClass pc = classes.next();
// Collecting information from annotations on the persistent class pc // Ensure we're in POJO, not dynamic model, mapping.
final AnnotationsMetadataReader annotationsMetadataReader = if (pc.getClassName() != null) {
new AnnotationsMetadataReader( globalCfg, reflectionManager, pc ); // Collecting information from annotations on the persistent class pc
final ClassAuditingData auditData = annotationsMetadataReader.getAuditData(); final AnnotationsMetadataReader annotationsMetadataReader =
new AnnotationsMetadataReader(globalCfg, reflectionManager, pc);
final ClassAuditingData auditData = annotationsMetadataReader.getAuditData();
classesAuditingData.addClassAuditingData( pc, auditData ); classesAuditingData.addClassAuditingData(pc, auditData);
}
} }
// Now that all information is read we can update the calculated fields. // Now that all information is read we can update the calculated fields.

View File

@ -23,11 +23,8 @@
*/ */
package org.hibernate.envers.configuration.internal; package org.hibernate.envers.configuration.internal;
import java.util.Date; import org.dom4j.Document;
import java.util.Iterator; import org.dom4j.Element;
import java.util.Set;
import javax.persistence.Column;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.annotations.common.reflection.ReflectionManager; import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.annotations.common.reflection.XClass; import org.hibernate.annotations.common.reflection.XClass;
@ -58,8 +55,10 @@ import org.hibernate.mapping.PersistentClass;
import org.hibernate.type.LongType; import org.hibernate.type.LongType;
import org.hibernate.type.Type; import org.hibernate.type.Type;
import org.dom4j.Document; import javax.persistence.Column;
import org.dom4j.Element; import java.util.Date;
import java.util.Iterator;
import java.util.Set;
/** /**
* @author Adam Warski (adam at warski dot org) * @author Adam Warski (adam at warski dot org)
@ -319,77 +318,78 @@ public class RevisionInfoConfiguration {
final Iterator<PersistentClass> classes = cfg.getClassMappings(); final Iterator<PersistentClass> classes = cfg.getClassMappings();
while ( classes.hasNext() ) { while ( classes.hasNext() ) {
PersistentClass pc = classes.next(); PersistentClass pc = classes.next();
XClass clazz; // Ensure we're in POJO, not dynamic model, mapping.
try { if (pc.getClassName() != null) {
clazz = reflectionManager.classForName( pc.getClassName(), this.getClass() ); XClass clazz;
} try {
catch (ClassNotFoundException e) { clazz = reflectionManager.classForName(pc.getClassName(), this.getClass());
throw new MappingException( e ); } catch (ClassNotFoundException e) {
} throw new MappingException(e);
final RevisionEntity revisionEntity = clazz.getAnnotation( RevisionEntity.class );
if ( revisionEntity != null ) {
if ( revisionEntityFound ) {
throw new MappingException( "Only one entity may be annotated with @RevisionEntity!" );
} }
// Checking if custom revision entity isn't audited final RevisionEntity revisionEntity = clazz.getAnnotation(RevisionEntity.class);
if ( clazz.getAnnotation( Audited.class ) != null ) { if (revisionEntity != null) {
throw new MappingException( "An entity annotated with @RevisionEntity cannot be audited!" ); if (revisionEntityFound) {
} throw new MappingException("Only one entity may be annotated with @RevisionEntity!");
}
revisionEntityFound = true; // Checking if custom revision entity isn't audited
if (clazz.getAnnotation(Audited.class) != null) {
throw new MappingException("An entity annotated with @RevisionEntity cannot be audited!");
}
final MutableBoolean revisionNumberFound = new MutableBoolean(); revisionEntityFound = true;
final MutableBoolean revisionTimestampFound = new MutableBoolean();
final MutableBoolean modifiedEntityNamesFound = new MutableBoolean();
searchForRevisionInfoCfg( final MutableBoolean revisionNumberFound = new MutableBoolean();
clazz, final MutableBoolean revisionTimestampFound = new MutableBoolean();
reflectionManager, final MutableBoolean modifiedEntityNamesFound = new MutableBoolean();
revisionNumberFound,
revisionTimestampFound,
modifiedEntityNamesFound
);
if ( !revisionNumberFound.isSet() ) { searchForRevisionInfoCfg(
throw new MappingException( clazz,
"An entity annotated with @RevisionEntity must have a field annotated " + reflectionManager,
"with @RevisionNumber!" revisionNumberFound,
revisionTimestampFound,
modifiedEntityNamesFound
); );
}
if ( !revisionTimestampFound.isSet() ) { if (!revisionNumberFound.isSet()) {
throw new MappingException( throw new MappingException(
"An entity annotated with @RevisionEntity must have a field annotated " + "An entity annotated with @RevisionEntity must have a field annotated " +
"with @RevisionTimestamp!" "with @RevisionNumber!"
); );
} }
revisionInfoEntityName = pc.getEntityName(); if (!revisionTimestampFound.isSet()) {
revisionInfoClass = pc.getMappedClass(); throw new MappingException(
final Class<? extends RevisionListener> revisionListenerClass = getRevisionListenerClass( revisionEntity.value() ); "An entity annotated with @RevisionEntity must have a field annotated " +
revisionInfoTimestampType = pc.getProperty( revisionInfoTimestampData.getName() ).getType(); "with @RevisionTimestamp!"
if ( globalCfg.isTrackEntitiesChangedInRevision() );
|| (globalCfg.isUseRevisionEntityWithNativeId() && DefaultTrackingModifiedEntitiesRevisionEntity.class }
.isAssignableFrom( revisionInfoClass ))
|| (!globalCfg.isUseRevisionEntityWithNativeId() && SequenceIdTrackingModifiedEntitiesRevisionEntity.class revisionInfoEntityName = pc.getEntityName();
.isAssignableFrom( revisionInfoClass )) revisionInfoClass = pc.getMappedClass();
|| modifiedEntityNamesFound.isSet() ) { final Class<? extends RevisionListener> revisionListenerClass = getRevisionListenerClass(revisionEntity.value());
// If tracking modified entities parameter is enabled, custom revision info entity is a subtype revisionInfoTimestampType = pc.getProperty(revisionInfoTimestampData.getName()).getType();
// of DefaultTrackingModifiedEntitiesRevisionEntity class, or @ModifiedEntityNames annotation is used. if (globalCfg.isTrackEntitiesChangedInRevision()
revisionInfoGenerator = new DefaultTrackingModifiedEntitiesRevisionInfoGenerator( || (globalCfg.isUseRevisionEntityWithNativeId() && DefaultTrackingModifiedEntitiesRevisionEntity.class
revisionInfoEntityName, .isAssignableFrom(revisionInfoClass))
revisionInfoClass, revisionListenerClass, revisionInfoTimestampData, isTimestampAsDate(), || (!globalCfg.isUseRevisionEntityWithNativeId() && SequenceIdTrackingModifiedEntitiesRevisionEntity.class
modifiedEntityNamesData .isAssignableFrom(revisionInfoClass))
); || modifiedEntityNamesFound.isSet()) {
globalCfg.setTrackEntitiesChangedInRevision( true ); // If tracking modified entities parameter is enabled, custom revision info entity is a subtype
} // of DefaultTrackingModifiedEntitiesRevisionEntity class, or @ModifiedEntityNames annotation is used.
else { revisionInfoGenerator = new DefaultTrackingModifiedEntitiesRevisionInfoGenerator(
revisionInfoGenerator = new DefaultRevisionInfoGenerator( revisionInfoEntityName,
revisionInfoEntityName, revisionInfoClass, revisionInfoClass, revisionListenerClass, revisionInfoTimestampData, isTimestampAsDate(),
revisionListenerClass, revisionInfoTimestampData, isTimestampAsDate() modifiedEntityNamesData
); );
globalCfg.setTrackEntitiesChangedInRevision(true);
} else {
revisionInfoGenerator = new DefaultRevisionInfoGenerator(
revisionInfoEntityName, revisionInfoClass,
revisionListenerClass, revisionInfoTimestampData, isTimestampAsDate()
);
}
} }
} }
} }

View File

@ -1,13 +1,12 @@
package org.hibernate.envers.test.integration.dynamicmodel; package org.hibernate.envers.test.integration.dynamicmodel;
import static org.junit.Assert.assertNotNull; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
import org.hibernate.testing.TestForIssue;
import org.junit.Test;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import static org.junit.Assert.assertNotNull;
import org.hibernate.testing.FailureExpected;
import org.hibernate.testing.TestForIssue;
import org.junit.Test;
/** /**
* @author Felix Feisst (feisst dot felix at gmail dot com) * @author Felix Feisst (feisst dot felix at gmail dot com)
@ -24,7 +23,6 @@ public class DynamicModelTest extends BaseEnversJPAFunctionalTestCase {
* Tests that an EntityManager can be created when using a dynamic model mapping. * Tests that an EntityManager can be created when using a dynamic model mapping.
*/ */
@Test @Test
@FailureExpected(jiraKey = "HHH-8769")
public void testDynamicModelMapping() { public void testDynamicModelMapping() {
EntityManager entityManager = getOrCreateEntityManager(); EntityManager entityManager = getOrCreateEntityManager();
assertNotNull( "Expected an entity manager to be returned", entityManager ); assertNotNull( "Expected an entity manager to be returned", entityManager );