Merge pull request #176 from lukasz-antoniak/HHH-6696
HHH-6696 - Allow specifying revision listener apart from @RevisionEntity annotation
This commit is contained in:
commit
550865e3d3
|
@ -407,7 +407,11 @@
|
|||
You tell Envers your custom <interfacename>org.hibernate.envers.RevisionListener</interfacename>
|
||||
implementation to use by specifying it on the
|
||||
<interfacename>@org.hibernate.envers.RevisionEntity</interfacename> annotation, using the
|
||||
<methodname>value</methodname> attribute.
|
||||
<methodname>value</methodname> attribute. If your <interfacename>RevisionListener</interfacename>
|
||||
class is inaccessible from <interfacename>@RevisionEntity</interfacename> (e.g. exists in a different
|
||||
module), set <property>org.hibernate.envers.revision_listener</property> property to it's fully
|
||||
qualified name. Class name defined by the configuration parameter overrides revision entity's
|
||||
<methodname>value</methodname> attribute.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.envers.configuration;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.envers.RevisionListener;
|
||||
|
||||
import static org.hibernate.envers.tools.Tools.getProperty;
|
||||
import java.util.Properties;
|
||||
|
||||
|
@ -49,6 +52,9 @@ public class GlobalConfiguration {
|
|||
// Should Envers track (persist) entity names that have been changed during each revision.
|
||||
private boolean trackEntitiesChangedInRevisionEnabled;
|
||||
|
||||
// Revision listener class name.
|
||||
private final Class<? extends RevisionListener> revisionListenerClass;
|
||||
|
||||
/*
|
||||
Which operator to use in correlated subqueries (when we want a property to be equal to the result of
|
||||
a correlated subquery, for example: e.p <operator> (select max(e2.p) where e2.p2 = e.p2 ...).
|
||||
|
@ -87,6 +93,17 @@ public class GlobalConfiguration {
|
|||
"org.hibernate.envers.track_entities_changed_in_revision",
|
||||
"false");
|
||||
trackEntitiesChangedInRevisionEnabled = Boolean.parseBoolean(trackEntitiesChangedInRevisionEnabledStr);
|
||||
|
||||
String revisionListenerClassName = properties.getProperty("org.hibernate.envers.revision_listener", null);
|
||||
if (revisionListenerClassName != null) {
|
||||
try {
|
||||
revisionListenerClass = (Class<? extends RevisionListener>) Thread.currentThread().getContextClassLoader().loadClass(revisionListenerClassName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new MappingException("Revision listener class not found: " + revisionListenerClassName + ".", e);
|
||||
}
|
||||
} else {
|
||||
revisionListenerClass = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isGenerateRevisionsForCollections() {
|
||||
|
@ -120,4 +137,8 @@ public class GlobalConfiguration {
|
|||
public void setTrackEntitiesChangedInRevisionEnabled(boolean trackEntitiesChangedInRevisionEnabled) {
|
||||
this.trackEntitiesChangedInRevisionEnabled = trackEntitiesChangedInRevisionEnabled;
|
||||
}
|
||||
|
||||
public Class<? extends RevisionListener> getRevisionListenerClass() {
|
||||
return revisionListenerClass;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -286,8 +286,8 @@ public class RevisionInfoConfiguration {
|
|||
}
|
||||
|
||||
revisionInfoEntityName = pc.getEntityName();
|
||||
|
||||
revisionInfoClass = pc.getMappedClass();
|
||||
Class<? extends RevisionListener> revisionListenerClass = getRevisionListenerClass(revisionEntity.value());
|
||||
revisionInfoTimestampType = pc.getProperty(revisionInfoTimestampData.getName()).getType();
|
||||
if (globalCfg.isTrackEntitiesChangedInRevisionEnabled() ||
|
||||
DefaultTrackingModifiedEntitiesRevisionEntity.class.isAssignableFrom(revisionInfoClass) ||
|
||||
|
@ -295,12 +295,12 @@ public class RevisionInfoConfiguration {
|
|||
// If tracking modified entities parameter is enabled, custom revision info entity is a subtype
|
||||
// of DefaultTrackingModifiedEntitiesRevisionEntity class, or @ModifiedEntityNames annotation is used.
|
||||
revisionInfoGenerator = new DefaultTrackingModifiedEntitiesRevisionInfoGenerator(revisionInfoEntityName,
|
||||
revisionInfoClass, revisionEntity.value(), revisionInfoTimestampData, isTimestampAsDate(),
|
||||
revisionInfoClass, revisionListenerClass, revisionInfoTimestampData, isTimestampAsDate(),
|
||||
modifiedEntityNamesData);
|
||||
globalCfg.setTrackEntitiesChangedInRevisionEnabled(true);
|
||||
} else {
|
||||
revisionInfoGenerator = new DefaultRevisionInfoGenerator(revisionInfoEntityName, revisionInfoClass,
|
||||
revisionEntity.value(), revisionInfoTimestampData, isTimestampAsDate());
|
||||
revisionListenerClass, revisionInfoTimestampData, isTimestampAsDate());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -308,16 +308,18 @@ public class RevisionInfoConfiguration {
|
|||
// In case of a custom revision info generator, the mapping will be null.
|
||||
Document revisionInfoXmlMapping = null;
|
||||
|
||||
Class<? extends RevisionListener> revisionListenerClass = getRevisionListenerClass(RevisionListener.class);
|
||||
|
||||
if (revisionInfoGenerator == null) {
|
||||
if (globalCfg.isTrackEntitiesChangedInRevisionEnabled()) {
|
||||
revisionInfoClass = DefaultTrackingModifiedEntitiesRevisionEntity.class;
|
||||
revisionInfoEntityName = DefaultTrackingModifiedEntitiesRevisionEntity.class.getName();
|
||||
revisionInfoGenerator = new DefaultTrackingModifiedEntitiesRevisionInfoGenerator(revisionInfoEntityName, revisionInfoClass,
|
||||
RevisionListener.class, revisionInfoTimestampData, isTimestampAsDate(), modifiedEntityNamesData);
|
||||
revisionListenerClass, revisionInfoTimestampData, isTimestampAsDate(), modifiedEntityNamesData);
|
||||
} else {
|
||||
revisionInfoClass = DefaultRevisionEntity.class;
|
||||
revisionInfoGenerator = new DefaultRevisionInfoGenerator(revisionInfoEntityName, revisionInfoClass,
|
||||
RevisionListener.class, revisionInfoTimestampData, isTimestampAsDate());
|
||||
revisionListenerClass, revisionInfoTimestampData, isTimestampAsDate());
|
||||
}
|
||||
revisionInfoXmlMapping = generateDefaultRevisionInfoXmlMapping();
|
||||
}
|
||||
|
@ -337,6 +339,18 @@ public class RevisionInfoConfiguration {
|
|||
String typename = revisionInfoTimestampType.getName();
|
||||
return "date".equals(typename) || "time".equals(typename) || "timestamp".equals(typename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param defaultListener Revision listener that shall be applied if {@code org.hibernate.envers.revision_listener}
|
||||
* parameter has not been set.
|
||||
* @return Revision listener.
|
||||
*/
|
||||
private Class<? extends RevisionListener> getRevisionListenerClass(Class<? extends RevisionListener> defaultListener) {
|
||||
if (globalCfg.getRevisionListenerClass() != null) {
|
||||
return globalCfg.getRevisionListenerClass();
|
||||
}
|
||||
return defaultListener;
|
||||
}
|
||||
}
|
||||
|
||||
class RevisionInfoConfigurationResult {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package org.hibernate.envers.test.integration.reventity;
|
||||
|
||||
import org.hibernate.envers.RevisionListener;
|
||||
|
||||
/**
|
||||
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||
*/
|
||||
public class CountingRevisionListener implements RevisionListener {
|
||||
public static int revisionCount = 0;
|
||||
|
||||
@Override
|
||||
public void newRevision(Object revisionEntity) {
|
||||
++revisionCount;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package org.hibernate.envers.test.integration.reventity;
|
||||
|
||||
import org.hibernate.ejb.Ejb3Configuration;
|
||||
import org.hibernate.envers.test.AbstractEntityTest;
|
||||
import org.hibernate.envers.test.Priority;
|
||||
import org.hibernate.envers.test.entities.StrTestEntity;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
/**
|
||||
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||
*/
|
||||
@TestForIssue(jiraKey = "HHH-6696")
|
||||
public class GloballyConfiguredRevListenerTest extends AbstractEntityTest {
|
||||
public void configure(Ejb3Configuration cfg) {
|
||||
cfg.addAnnotatedClass(StrTestEntity.class);
|
||||
cfg.setProperty("org.hibernate.envers.revision_listener", "org.hibernate.envers.test.integration.reventity.CountingRevisionListener");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Priority(10)
|
||||
public void initData() {
|
||||
EntityManager em = getEntityManager();
|
||||
|
||||
CountingRevisionListener.revisionCount = 0;
|
||||
|
||||
// Revision 1
|
||||
em.getTransaction().begin();
|
||||
StrTestEntity te = new StrTestEntity("data");
|
||||
em.persist(te);
|
||||
em.getTransaction().commit();
|
||||
|
||||
Assert.assertEquals(1, CountingRevisionListener.revisionCount);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package org.hibernate.envers.test.integration.reventity;
|
||||
|
||||
import org.hibernate.ejb.Ejb3Configuration;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
|
||||
/**
|
||||
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||
*/
|
||||
@TestForIssue(jiraKey = "HHH-6696")
|
||||
public class OverrideCustomRevListenerTest extends GloballyConfiguredRevListenerTest {
|
||||
@Override
|
||||
public void configure(Ejb3Configuration cfg) {
|
||||
super.configure(cfg);
|
||||
cfg.addAnnotatedClass(ListenerRevEntity.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package org.hibernate.envers.test.integration.reventity;
|
||||
|
||||
import org.hibernate.ejb.Ejb3Configuration;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
|
||||
/**
|
||||
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||
*/
|
||||
@TestForIssue(jiraKey = "HHH-6696")
|
||||
public class OverrideDefaultRevListenerTest extends GloballyConfiguredRevListenerTest {
|
||||
@Override
|
||||
public void configure(Ejb3Configuration cfg) {
|
||||
super.configure(cfg);
|
||||
cfg.addAnnotatedClass(LongRevNumberRevEntity.class);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue