HHH-7478 - Fix and test
This commit is contained in:
parent
7778aae3b7
commit
6be8b4aad0
|
@ -32,7 +32,9 @@ import java.util.HashMap;
|
|||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
@ -643,7 +645,9 @@ public class ActionQueue {
|
|||
|
||||
private static class BeforeTransactionCompletionProcessQueue {
|
||||
private SessionImplementor session;
|
||||
private List<BeforeTransactionCompletionProcess> processes = new ArrayList<BeforeTransactionCompletionProcess>();
|
||||
// Concurrency handling required when transaction completion process is dynamically registered
|
||||
// inside event listener (HHH-7478).
|
||||
private Queue<BeforeTransactionCompletionProcess> processes = new ConcurrentLinkedQueue<BeforeTransactionCompletionProcess>();
|
||||
|
||||
private BeforeTransactionCompletionProcessQueue(SessionImplementor session) {
|
||||
this.session = session;
|
||||
|
@ -675,8 +679,9 @@ public class ActionQueue {
|
|||
private static class AfterTransactionCompletionProcessQueue {
|
||||
private SessionImplementor session;
|
||||
private Set<String> querySpacesToInvalidate = new HashSet<String>();
|
||||
private List<AfterTransactionCompletionProcess> processes
|
||||
= new ArrayList<AfterTransactionCompletionProcess>( INIT_QUEUE_LIST_SIZE * 3 );
|
||||
// Concurrency handling required when transaction completion process is dynamically registered
|
||||
// inside event listener (HHH-7478).
|
||||
private Queue<AfterTransactionCompletionProcess> processes = new ConcurrentLinkedQueue<AfterTransactionCompletionProcess>();
|
||||
|
||||
private AfterTransactionCompletionProcessQueue(SessionImplementor session) {
|
||||
this.session = session;
|
||||
|
|
|
@ -23,17 +23,32 @@
|
|||
*/
|
||||
package org.hibernate.envers.internal.tools;
|
||||
|
||||
|
||||
/**
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
*/
|
||||
public class MutableInteger {
|
||||
private int value;
|
||||
private int value = 0;
|
||||
|
||||
public MutableInteger() {
|
||||
}
|
||||
|
||||
public MutableInteger(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getAndIncrease() {
|
||||
return value++;
|
||||
}
|
||||
|
||||
public int get() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void set(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void increase() {
|
||||
++value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package org.hibernate.envers.test.integration.basic;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.action.spi.AfterTransactionCompletionProcess;
|
||||
import org.hibernate.action.spi.BeforeTransactionCompletionProcess;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.envers.test.BaseEnversFunctionalTestCase;
|
||||
import org.hibernate.envers.test.entities.StrTestEntity;
|
||||
import org.hibernate.envers.tools.MutableInteger;
|
||||
import org.hibernate.event.service.spi.EventListenerRegistry;
|
||||
import org.hibernate.event.spi.EventType;
|
||||
import org.hibernate.event.spi.PostInsertEvent;
|
||||
import org.hibernate.event.spi.PostInsertEventListener;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
|
||||
/**
|
||||
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||
*/
|
||||
public class RegisterUserEventListenersTest extends BaseEnversFunctionalTestCase {
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] { StrTestEntity.class };
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-7478" )
|
||||
public void testTransactionProcessSynchronization() {
|
||||
final EventListenerRegistry registry = sessionFactory().getServiceRegistry().getService( EventListenerRegistry.class );
|
||||
final CountingPostInsertTransactionBoundaryListener listener = new CountingPostInsertTransactionBoundaryListener();
|
||||
|
||||
registry.getEventListenerGroup( EventType.POST_INSERT ).appendListener( listener );
|
||||
|
||||
Session session = openSession();
|
||||
session.getTransaction().begin();
|
||||
StrTestEntity entity = new StrTestEntity( "str1" );
|
||||
session.save( entity );
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
|
||||
// Post insert listener invoked three times - before/after insertion of original data,
|
||||
// revision entity and audit row.
|
||||
Assert.assertEquals( 3, listener.getBeforeCount() );
|
||||
Assert.assertEquals( 3, listener.getAfterCount() );
|
||||
}
|
||||
|
||||
private static class CountingPostInsertTransactionBoundaryListener implements PostInsertEventListener {
|
||||
private final MutableInteger beforeCounter = new MutableInteger();
|
||||
private final MutableInteger afterCounter = new MutableInteger();
|
||||
|
||||
@Override
|
||||
public void onPostInsert(PostInsertEvent event) {
|
||||
event.getSession().getActionQueue().registerProcess(new BeforeTransactionCompletionProcess() {
|
||||
@Override
|
||||
public void doBeforeTransactionCompletion(SessionImplementor session) {
|
||||
beforeCounter.increase();
|
||||
}
|
||||
});
|
||||
event.getSession().getActionQueue().registerProcess(new AfterTransactionCompletionProcess() {
|
||||
@Override
|
||||
public void doAfterTransactionCompletion(boolean success, SessionImplementor session) {
|
||||
afterCounter.increase();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresPostCommitHanding(EntityPersister persister) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getBeforeCount() {
|
||||
return beforeCounter.get();
|
||||
}
|
||||
|
||||
public int getAfterCount() {
|
||||
return afterCounter.get();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue