HHH-1582 - Added explicit PostCommit(Insert|Delete|Update)EvenLister interfaces to allow for separation of success/fail handling in post commit events.
Maintained current behavior by having the Entity actions call the existing API unless using one of the new interfaces. Added 2 test cases, 1 using the new interfaces and 1 using the existing interfaces.
(cherry picked from commit c6ca3a4ef2
)
This commit is contained in:
parent
96d60ba05d
commit
4f963a6fb4
|
@ -34,6 +34,7 @@ import org.hibernate.engine.spi.PersistenceContext;
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.event.service.spi.EventListenerGroup;
|
import org.hibernate.event.service.spi.EventListenerGroup;
|
||||||
import org.hibernate.event.spi.EventType;
|
import org.hibernate.event.spi.EventType;
|
||||||
|
import org.hibernate.event.spi.PostCommitDeleteEventListener;
|
||||||
import org.hibernate.event.spi.PostDeleteEvent;
|
import org.hibernate.event.spi.PostDeleteEvent;
|
||||||
import org.hibernate.event.spi.PostDeleteEventListener;
|
import org.hibernate.event.spi.PostDeleteEventListener;
|
||||||
import org.hibernate.event.spi.PreDeleteEvent;
|
import org.hibernate.event.spi.PreDeleteEvent;
|
||||||
|
@ -170,7 +171,7 @@ public class EntityDeleteAction extends EntityAction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void postCommitDelete() {
|
private void postCommitDelete(boolean success) {
|
||||||
final EventListenerGroup<PostDeleteEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_DELETE );
|
final EventListenerGroup<PostDeleteEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_DELETE );
|
||||||
if ( listenerGroup.isEmpty() ) {
|
if ( listenerGroup.isEmpty() ) {
|
||||||
return;
|
return;
|
||||||
|
@ -182,8 +183,19 @@ public class EntityDeleteAction extends EntityAction {
|
||||||
getPersister(),
|
getPersister(),
|
||||||
eventSource()
|
eventSource()
|
||||||
);
|
);
|
||||||
for( PostDeleteEventListener listener : listenerGroup.listeners() ){
|
for ( PostDeleteEventListener listener : listenerGroup.listeners() ) {
|
||||||
listener.onPostDelete( event );
|
if ( PostCommitDeleteEventListener.class.isInstance( listener ) ) {
|
||||||
|
if ( success ) {
|
||||||
|
listener.onPostDelete( event );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
((PostCommitDeleteEventListener) listener).onPostDeleteCommitFailed( event );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//default to the legacy implementation that always fires the event
|
||||||
|
listener.onPostDelete( event );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,7 +209,7 @@ public class EntityDeleteAction extends EntityAction {
|
||||||
);
|
);
|
||||||
getPersister().getCacheAccessStrategy().unlockItem( ck, lock );
|
getPersister().getCacheAccessStrategy().unlockItem( ck, lock );
|
||||||
}
|
}
|
||||||
postCommitDelete();
|
postCommitDelete( success );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.hibernate.engine.spi.EntityKey;
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.event.service.spi.EventListenerGroup;
|
import org.hibernate.event.service.spi.EventListenerGroup;
|
||||||
import org.hibernate.event.spi.EventType;
|
import org.hibernate.event.spi.EventType;
|
||||||
|
import org.hibernate.event.spi.PostCommitInsertEventListener;
|
||||||
import org.hibernate.event.spi.PostInsertEvent;
|
import org.hibernate.event.spi.PostInsertEvent;
|
||||||
import org.hibernate.event.spi.PostInsertEventListener;
|
import org.hibernate.event.spi.PostInsertEventListener;
|
||||||
import org.hibernate.event.spi.PreInsertEvent;
|
import org.hibernate.event.spi.PreInsertEvent;
|
||||||
|
@ -149,7 +150,7 @@ public final class EntityIdentityInsertAction extends AbstractEntityInsertAction
|
||||||
if ( success && persister.hasCache() && !persister.isCacheInvalidationRequired() ) {
|
if ( success && persister.hasCache() && !persister.isCacheInvalidationRequired() ) {
|
||||||
persister.getCache().afterInsert( getGeneratedId(), cacheEntry );
|
persister.getCache().afterInsert( getGeneratedId(), cacheEntry );
|
||||||
}*/
|
}*/
|
||||||
postCommitInsert();
|
postCommitInsert( success );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void postInsert() {
|
private void postInsert() {
|
||||||
|
@ -173,7 +174,7 @@ public final class EntityIdentityInsertAction extends AbstractEntityInsertAction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void postCommitInsert() {
|
private void postCommitInsert(boolean success) {
|
||||||
final EventListenerGroup<PostInsertEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_INSERT );
|
final EventListenerGroup<PostInsertEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_INSERT );
|
||||||
if ( listenerGroup.isEmpty() ) {
|
if ( listenerGroup.isEmpty() ) {
|
||||||
return;
|
return;
|
||||||
|
@ -186,7 +187,18 @@ public final class EntityIdentityInsertAction extends AbstractEntityInsertAction
|
||||||
eventSource()
|
eventSource()
|
||||||
);
|
);
|
||||||
for ( PostInsertEventListener listener : listenerGroup.listeners() ) {
|
for ( PostInsertEventListener listener : listenerGroup.listeners() ) {
|
||||||
listener.onPostInsert( event );
|
if ( PostCommitInsertEventListener.class.isInstance( listener ) ) {
|
||||||
|
if ( success ) {
|
||||||
|
listener.onPostInsert( event );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
((PostCommitInsertEventListener) listener).onPostInsertCommitFailed( event );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//default to the legacy implementation that always fires the event
|
||||||
|
listener.onPostInsert( event );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.event.service.spi.EventListenerGroup;
|
import org.hibernate.event.service.spi.EventListenerGroup;
|
||||||
import org.hibernate.event.spi.EventType;
|
import org.hibernate.event.spi.EventType;
|
||||||
|
import org.hibernate.event.spi.PostCommitInsertEventListener;
|
||||||
import org.hibernate.event.spi.PostInsertEvent;
|
import org.hibernate.event.spi.PostInsertEvent;
|
||||||
import org.hibernate.event.spi.PostInsertEventListener;
|
import org.hibernate.event.spi.PostInsertEventListener;
|
||||||
import org.hibernate.event.spi.PreInsertEvent;
|
import org.hibernate.event.spi.PreInsertEvent;
|
||||||
|
@ -177,7 +178,7 @@ public final class EntityInsertAction extends AbstractEntityInsertAction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void postCommitInsert() {
|
private void postCommitInsert(boolean success) {
|
||||||
final EventListenerGroup<PostInsertEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_INSERT );
|
final EventListenerGroup<PostInsertEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_INSERT );
|
||||||
if ( listenerGroup.isEmpty() ) {
|
if ( listenerGroup.isEmpty() ) {
|
||||||
return;
|
return;
|
||||||
|
@ -190,7 +191,18 @@ public final class EntityInsertAction extends AbstractEntityInsertAction {
|
||||||
eventSource()
|
eventSource()
|
||||||
);
|
);
|
||||||
for ( PostInsertEventListener listener : listenerGroup.listeners() ) {
|
for ( PostInsertEventListener listener : listenerGroup.listeners() ) {
|
||||||
listener.onPostInsert( event );
|
if ( PostCommitInsertEventListener.class.isInstance( listener ) ) {
|
||||||
|
if ( success ) {
|
||||||
|
listener.onPostInsert( event );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
((PostCommitInsertEventListener) listener).onPostInsertCommitFailed( event );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//default to the legacy implementation that always fires the event
|
||||||
|
listener.onPostInsert( event );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +232,7 @@ public final class EntityInsertAction extends AbstractEntityInsertAction {
|
||||||
.secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
|
.secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
postCommitInsert();
|
postCommitInsert( success );
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean cacheAfterInsert(EntityPersister persister, CacheKey ck) {
|
private boolean cacheAfterInsert(EntityPersister persister, CacheKey ck) {
|
||||||
|
|
|
@ -39,6 +39,7 @@ import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.engine.spi.Status;
|
import org.hibernate.engine.spi.Status;
|
||||||
import org.hibernate.event.service.spi.EventListenerGroup;
|
import org.hibernate.event.service.spi.EventListenerGroup;
|
||||||
import org.hibernate.event.spi.EventType;
|
import org.hibernate.event.spi.EventType;
|
||||||
|
import org.hibernate.event.spi.PostCommitUpdateEventListener;
|
||||||
import org.hibernate.event.spi.PostUpdateEvent;
|
import org.hibernate.event.spi.PostUpdateEvent;
|
||||||
import org.hibernate.event.spi.PostUpdateEventListener;
|
import org.hibernate.event.spi.PostUpdateEventListener;
|
||||||
import org.hibernate.event.spi.PreUpdateEvent;
|
import org.hibernate.event.spi.PreUpdateEvent;
|
||||||
|
@ -277,7 +278,7 @@ public final class EntityUpdateAction extends EntityAction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void postCommitUpdate() {
|
private void postCommitUpdate(boolean success) {
|
||||||
final EventListenerGroup<PostUpdateEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_UPDATE );
|
final EventListenerGroup<PostUpdateEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_UPDATE );
|
||||||
if ( listenerGroup.isEmpty() ) {
|
if ( listenerGroup.isEmpty() ) {
|
||||||
return;
|
return;
|
||||||
|
@ -292,7 +293,18 @@ public final class EntityUpdateAction extends EntityAction {
|
||||||
eventSource()
|
eventSource()
|
||||||
);
|
);
|
||||||
for ( PostUpdateEventListener listener : listenerGroup.listeners() ) {
|
for ( PostUpdateEventListener listener : listenerGroup.listeners() ) {
|
||||||
listener.onPostUpdate( event );
|
if ( PostCommitUpdateEventListener.class.isInstance( listener ) ) {
|
||||||
|
if ( success ) {
|
||||||
|
listener.onPostUpdate( event );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
((PostCommitUpdateEventListener) listener).onPostUpdateCommitFailed( event );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//default to the legacy implementation that always fires the event
|
||||||
|
listener.onPostUpdate( event );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,7 +342,7 @@ public final class EntityUpdateAction extends EntityAction {
|
||||||
persister.getCacheAccessStrategy().unlockItem( ck, lock );
|
persister.getCacheAccessStrategy().unlockItem( ck, lock );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
postCommitUpdate();
|
postCommitUpdate( success );
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean cacheAfterUpdate(EntityPersister persister, CacheKey ck) {
|
private boolean cacheAfterUpdate(EntityPersister persister, CacheKey ck) {
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package org.hibernate.event.spi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after an entity delete is committed to the datastore.
|
||||||
|
*
|
||||||
|
* @author Shawn Clowater
|
||||||
|
*/
|
||||||
|
public interface PostCommitDeleteEventListener extends PostDeleteEventListener {
|
||||||
|
/**
|
||||||
|
* Called when a commit fails and an an entity was scheduled for deletion
|
||||||
|
*
|
||||||
|
* @param event the delete event to be handled
|
||||||
|
*/
|
||||||
|
public void onPostDeleteCommitFailed(PostDeleteEvent event);
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package org.hibernate.event.spi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after an entity insert is committed to the datastore.
|
||||||
|
*
|
||||||
|
* @author Shawn Clowater
|
||||||
|
*/
|
||||||
|
public interface PostCommitInsertEventListener extends PostInsertEventListener {
|
||||||
|
/**
|
||||||
|
* Called when a commit fails and an an entity was scheduled for insertion
|
||||||
|
*
|
||||||
|
* @param event the insert event to be handled
|
||||||
|
*/
|
||||||
|
public void onPostInsertCommitFailed(PostInsertEvent event);
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package org.hibernate.event.spi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after an entity update is committed to the datastore.
|
||||||
|
*
|
||||||
|
* @author Shawn Clowater
|
||||||
|
*/
|
||||||
|
public interface PostCommitUpdateEventListener extends PostUpdateEventListener {
|
||||||
|
/**
|
||||||
|
* Called when a commit fails and an an entity was scheduled for update
|
||||||
|
*
|
||||||
|
* @param event the update event to be handled
|
||||||
|
*/
|
||||||
|
public void onPostUpdateCommitFailed(PostUpdateEvent event);
|
||||||
|
}
|
|
@ -0,0 +1,265 @@
|
||||||
|
package org.hibernate.test.events;
|
||||||
|
|
||||||
|
import org.hibernate.IrrelevantEntity;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.Transaction;
|
||||||
|
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.event.service.spi.EventListenerRegistry;
|
||||||
|
import org.hibernate.event.spi.*;
|
||||||
|
import org.hibernate.integrator.spi.Integrator;
|
||||||
|
import org.hibernate.metamodel.source.MetadataImplementor;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test to ensure that the existing post commit behavior when using plain PostXEventListeners fire on both success and failure.
|
||||||
|
*
|
||||||
|
* @author ShawnClowater
|
||||||
|
*/
|
||||||
|
public class LegacyPostCommitListenerTest extends BaseCoreFunctionalTestCase {
|
||||||
|
private PostInsertEventListener postCommitInsertEventListener = new LegacyPostCommitInsertEventListener();
|
||||||
|
private PostDeleteEventListener postCommitDeleteEventListener = new LegacyPostCommitDeleteEventListener();
|
||||||
|
private PostUpdateEventListener postCommitUpdateEventListener = new LegacyPostCommitUpdateEventListener();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void prepareTest() throws Exception {
|
||||||
|
((LegacyPostCommitInsertEventListener) postCommitInsertEventListener).fired = 0;
|
||||||
|
((LegacyPostCommitDeleteEventListener) postCommitDeleteEventListener).fired = 0;
|
||||||
|
((LegacyPostCommitUpdateEventListener) postCommitUpdateEventListener).fired = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void prepareBootstrapRegistryBuilder(BootstrapServiceRegistryBuilder builder) {
|
||||||
|
super.prepareBootstrapRegistryBuilder( builder );
|
||||||
|
builder.with(
|
||||||
|
new Integrator() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void integrate(
|
||||||
|
Configuration configuration,
|
||||||
|
SessionFactoryImplementor sessionFactory,
|
||||||
|
SessionFactoryServiceRegistry serviceRegistry) {
|
||||||
|
integrate( serviceRegistry );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void integrate(
|
||||||
|
MetadataImplementor metadata,
|
||||||
|
SessionFactoryImplementor sessionFactory,
|
||||||
|
SessionFactoryServiceRegistry serviceRegistry) {
|
||||||
|
integrate( serviceRegistry );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void integrate(SessionFactoryServiceRegistry serviceRegistry) {
|
||||||
|
serviceRegistry.getService( EventListenerRegistry.class ).getEventListenerGroup(
|
||||||
|
EventType.POST_COMMIT_DELETE
|
||||||
|
).appendListener( postCommitDeleteEventListener );
|
||||||
|
serviceRegistry.getService( EventListenerRegistry.class ).getEventListenerGroup(
|
||||||
|
EventType.POST_COMMIT_UPDATE
|
||||||
|
).appendListener( postCommitUpdateEventListener );
|
||||||
|
serviceRegistry.getService( EventListenerRegistry.class ).getEventListenerGroup(
|
||||||
|
EventType.POST_COMMIT_INSERT
|
||||||
|
).appendListener( postCommitInsertEventListener );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disintegrate(
|
||||||
|
SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-1582")
|
||||||
|
public void testPostCommitInsertListenerSuccess() {
|
||||||
|
Session session = openSession();
|
||||||
|
Transaction transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
IrrelevantEntity irrelevantEntity = new IrrelevantEntity();
|
||||||
|
irrelevantEntity.setName( "Irrelevant" );
|
||||||
|
|
||||||
|
session.save( irrelevantEntity );
|
||||||
|
session.flush();
|
||||||
|
transaction.commit();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
Assert.assertEquals( 1, ((LegacyPostCommitInsertEventListener) postCommitInsertEventListener).fired );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-1582")
|
||||||
|
public void testPostCommitInsertListenerRollback() {
|
||||||
|
Session session = openSession();
|
||||||
|
Transaction transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
IrrelevantEntity irrelevantEntity = new IrrelevantEntity();
|
||||||
|
irrelevantEntity.setName( "Irrelevant" );
|
||||||
|
|
||||||
|
session.save( irrelevantEntity );
|
||||||
|
session.flush();
|
||||||
|
transaction.rollback();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
//the legacy implementation fires the listener on failure as well
|
||||||
|
Assert.assertEquals( 1, ((LegacyPostCommitInsertEventListener) postCommitInsertEventListener).fired );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-1582")
|
||||||
|
public void testPostCommitUpdateListenerSuccess() {
|
||||||
|
Session session = openSession();
|
||||||
|
Transaction transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
IrrelevantEntity irrelevantEntity = new IrrelevantEntity();
|
||||||
|
irrelevantEntity.setName( "Irrelevant" );
|
||||||
|
|
||||||
|
session.save( irrelevantEntity );
|
||||||
|
session.flush();
|
||||||
|
transaction.commit();
|
||||||
|
|
||||||
|
session = openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
irrelevantEntity.setName( "Irrelevant 2" );
|
||||||
|
session.update( irrelevantEntity );
|
||||||
|
session.flush();
|
||||||
|
transaction.commit();
|
||||||
|
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
Assert.assertEquals( 1, ((LegacyPostCommitUpdateEventListener) postCommitUpdateEventListener).fired );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-1582")
|
||||||
|
public void testPostCommitUpdateListenerRollback() {
|
||||||
|
Session session = openSession();
|
||||||
|
Transaction transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
IrrelevantEntity irrelevantEntity = new IrrelevantEntity();
|
||||||
|
irrelevantEntity.setName( "Irrelevant" );
|
||||||
|
|
||||||
|
session.save( irrelevantEntity );
|
||||||
|
session.flush();
|
||||||
|
transaction.commit();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
session = openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
irrelevantEntity.setName( "Irrelevant 2" );
|
||||||
|
session.update( irrelevantEntity );
|
||||||
|
session.flush();
|
||||||
|
transaction.rollback();
|
||||||
|
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
//the legacy implementation fires the listener on failure as well
|
||||||
|
Assert.assertEquals( 1, ((LegacyPostCommitUpdateEventListener) postCommitUpdateEventListener).fired );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-1582")
|
||||||
|
public void testPostCommitDeleteListenerSuccess() {
|
||||||
|
Session session = openSession();
|
||||||
|
Transaction transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
IrrelevantEntity irrelevantEntity = new IrrelevantEntity();
|
||||||
|
irrelevantEntity.setName( "Irrelevant" );
|
||||||
|
|
||||||
|
session.save( irrelevantEntity );
|
||||||
|
session.flush();
|
||||||
|
transaction.commit();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
session = openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
session.delete( irrelevantEntity );
|
||||||
|
session.flush();
|
||||||
|
transaction.commit();
|
||||||
|
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
Assert.assertEquals( 1, ((LegacyPostCommitDeleteEventListener) postCommitDeleteEventListener).fired );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-1582")
|
||||||
|
public void testPostCommitDeleteListenerRollback() {
|
||||||
|
Session session = openSession();
|
||||||
|
Transaction transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
IrrelevantEntity irrelevantEntity = new IrrelevantEntity();
|
||||||
|
irrelevantEntity.setName( "Irrelevant" );
|
||||||
|
|
||||||
|
session.save( irrelevantEntity );
|
||||||
|
session.flush();
|
||||||
|
transaction.commit();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
session = openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
session.delete( irrelevantEntity );
|
||||||
|
session.flush();
|
||||||
|
transaction.rollback();
|
||||||
|
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
//the legacy implementation fires the listener on failure as well
|
||||||
|
Assert.assertEquals( 1, ((LegacyPostCommitDeleteEventListener) postCommitDeleteEventListener).fired );
|
||||||
|
}
|
||||||
|
|
||||||
|
private class LegacyPostCommitDeleteEventListener implements PostDeleteEventListener {
|
||||||
|
int fired;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPostDelete(PostDeleteEvent event) {
|
||||||
|
fired++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresPostCommitHanding(EntityPersister persister) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class LegacyPostCommitUpdateEventListener implements PostUpdateEventListener {
|
||||||
|
int fired;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPostUpdate(PostUpdateEvent event) {
|
||||||
|
fired++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresPostCommitHanding(EntityPersister persister) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class LegacyPostCommitInsertEventListener implements PostInsertEventListener {
|
||||||
|
int fired;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPostInsert(PostInsertEvent event) {
|
||||||
|
fired++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresPostCommitHanding(EntityPersister persister) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class[] {IrrelevantEntity.class};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,298 @@
|
||||||
|
package org.hibernate.test.events;
|
||||||
|
|
||||||
|
import org.hibernate.IrrelevantEntity;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.Transaction;
|
||||||
|
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.event.service.spi.EventListenerRegistry;
|
||||||
|
import org.hibernate.event.spi.EventType;
|
||||||
|
import org.hibernate.event.spi.PostCommitDeleteEventListener;
|
||||||
|
import org.hibernate.event.spi.PostCommitInsertEventListener;
|
||||||
|
import org.hibernate.event.spi.PostCommitUpdateEventListener;
|
||||||
|
import org.hibernate.event.spi.PostDeleteEvent;
|
||||||
|
import org.hibernate.event.spi.PostDeleteEventListener;
|
||||||
|
import org.hibernate.event.spi.PostInsertEvent;
|
||||||
|
import org.hibernate.event.spi.PostInsertEventListener;
|
||||||
|
import org.hibernate.event.spi.PostUpdateEvent;
|
||||||
|
import org.hibernate.event.spi.PostUpdateEventListener;
|
||||||
|
import org.hibernate.integrator.spi.Integrator;
|
||||||
|
import org.hibernate.metamodel.source.MetadataImplementor;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test to ensure that the existing post commit behavior when using plain PostXEventListeners fire on both success and failure.
|
||||||
|
*
|
||||||
|
* @author ShawnClowater
|
||||||
|
*/
|
||||||
|
public class PostCommitListenerTest extends BaseCoreFunctionalTestCase {
|
||||||
|
private PostInsertEventListener postCommitInsertEventListener = new TestPostCommitInsertEventListener();
|
||||||
|
private PostDeleteEventListener postCommitDeleteEventListener = new TestPostCommitDeleteEventListener();
|
||||||
|
private PostUpdateEventListener postCommitUpdateEventListener = new TestPostCommitUpdateEventListener();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void prepareTest() throws Exception {
|
||||||
|
((TestPostCommitInsertEventListener) postCommitInsertEventListener).success = 0;
|
||||||
|
((TestPostCommitInsertEventListener) postCommitInsertEventListener).failed = 0;
|
||||||
|
((TestPostCommitDeleteEventListener) postCommitDeleteEventListener).success = 0;
|
||||||
|
((TestPostCommitDeleteEventListener) postCommitDeleteEventListener).failed = 0;
|
||||||
|
((TestPostCommitUpdateEventListener) postCommitUpdateEventListener).sucess = 0;
|
||||||
|
((TestPostCommitUpdateEventListener) postCommitUpdateEventListener).failed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void prepareBootstrapRegistryBuilder(BootstrapServiceRegistryBuilder builder) {
|
||||||
|
super.prepareBootstrapRegistryBuilder( builder );
|
||||||
|
builder.with(
|
||||||
|
new Integrator() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void integrate(
|
||||||
|
Configuration configuration,
|
||||||
|
SessionFactoryImplementor sessionFactory,
|
||||||
|
SessionFactoryServiceRegistry serviceRegistry) {
|
||||||
|
integrate( serviceRegistry );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void integrate(
|
||||||
|
MetadataImplementor metadata,
|
||||||
|
SessionFactoryImplementor sessionFactory,
|
||||||
|
SessionFactoryServiceRegistry serviceRegistry) {
|
||||||
|
integrate( serviceRegistry );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void integrate(SessionFactoryServiceRegistry serviceRegistry) {
|
||||||
|
serviceRegistry.getService( EventListenerRegistry.class ).getEventListenerGroup(
|
||||||
|
EventType.POST_COMMIT_DELETE
|
||||||
|
).appendListener( postCommitDeleteEventListener );
|
||||||
|
serviceRegistry.getService( EventListenerRegistry.class ).getEventListenerGroup(
|
||||||
|
EventType.POST_COMMIT_UPDATE
|
||||||
|
).appendListener( postCommitUpdateEventListener );
|
||||||
|
serviceRegistry.getService( EventListenerRegistry.class ).getEventListenerGroup(
|
||||||
|
EventType.POST_COMMIT_INSERT
|
||||||
|
).appendListener( postCommitInsertEventListener );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disintegrate(
|
||||||
|
SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-1582")
|
||||||
|
public void testPostCommitInsertListenerSuccess() {
|
||||||
|
Session session = openSession();
|
||||||
|
Transaction transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
IrrelevantEntity irrelevantEntity = new IrrelevantEntity();
|
||||||
|
irrelevantEntity.setName( "Irrelevant" );
|
||||||
|
|
||||||
|
session.save( irrelevantEntity );
|
||||||
|
session.flush();
|
||||||
|
transaction.commit();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
Assert.assertEquals( 1, ((TestPostCommitInsertEventListener) postCommitInsertEventListener).success );
|
||||||
|
Assert.assertEquals( 0, ((TestPostCommitInsertEventListener) postCommitInsertEventListener).failed );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-1582")
|
||||||
|
public void testPostCommitInsertListenerRollback() {
|
||||||
|
Session session = openSession();
|
||||||
|
Transaction transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
IrrelevantEntity irrelevantEntity = new IrrelevantEntity();
|
||||||
|
irrelevantEntity.setName( "Irrelevant" );
|
||||||
|
|
||||||
|
session.save( irrelevantEntity );
|
||||||
|
session.flush();
|
||||||
|
transaction.rollback();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
Assert.assertEquals( 0, ((TestPostCommitInsertEventListener) postCommitInsertEventListener).success );
|
||||||
|
Assert.assertEquals( 1, ((TestPostCommitInsertEventListener) postCommitInsertEventListener).failed );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-1582")
|
||||||
|
public void testPostCommitUpdateListenerSuccess() {
|
||||||
|
Session session = openSession();
|
||||||
|
Transaction transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
IrrelevantEntity irrelevantEntity = new IrrelevantEntity();
|
||||||
|
irrelevantEntity.setName( "Irrelevant" );
|
||||||
|
|
||||||
|
session.save( irrelevantEntity );
|
||||||
|
session.flush();
|
||||||
|
transaction.commit();
|
||||||
|
|
||||||
|
session = openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
irrelevantEntity.setName( "Irrelevant 2" );
|
||||||
|
session.update( irrelevantEntity );
|
||||||
|
session.flush();
|
||||||
|
transaction.commit();
|
||||||
|
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
Assert.assertEquals( 1, ((TestPostCommitUpdateEventListener) postCommitUpdateEventListener).sucess );
|
||||||
|
Assert.assertEquals( 0, ((TestPostCommitUpdateEventListener) postCommitUpdateEventListener).failed );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-1582")
|
||||||
|
public void testPostCommitUpdateListenerRollback() {
|
||||||
|
Session session = openSession();
|
||||||
|
Transaction transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
IrrelevantEntity irrelevantEntity = new IrrelevantEntity();
|
||||||
|
irrelevantEntity.setName( "Irrelevant" );
|
||||||
|
|
||||||
|
session.save( irrelevantEntity );
|
||||||
|
session.flush();
|
||||||
|
transaction.commit();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
session = openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
irrelevantEntity.setName( "Irrelevant 2" );
|
||||||
|
session.update( irrelevantEntity );
|
||||||
|
session.flush();
|
||||||
|
transaction.rollback();
|
||||||
|
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
Assert.assertEquals( 0, ((TestPostCommitUpdateEventListener) postCommitUpdateEventListener).sucess );
|
||||||
|
Assert.assertEquals( 1, ((TestPostCommitUpdateEventListener) postCommitUpdateEventListener).failed );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-1582")
|
||||||
|
public void testPostCommitDeleteListenerSuccess() {
|
||||||
|
Session session = openSession();
|
||||||
|
Transaction transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
IrrelevantEntity irrelevantEntity = new IrrelevantEntity();
|
||||||
|
irrelevantEntity.setName( "Irrelevant" );
|
||||||
|
|
||||||
|
session.save( irrelevantEntity );
|
||||||
|
session.flush();
|
||||||
|
transaction.commit();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
session = openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
session.delete( irrelevantEntity );
|
||||||
|
session.flush();
|
||||||
|
transaction.commit();
|
||||||
|
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
Assert.assertEquals( 1, ((TestPostCommitDeleteEventListener) postCommitDeleteEventListener).success );
|
||||||
|
Assert.assertEquals( 0, ((TestPostCommitDeleteEventListener) postCommitDeleteEventListener).failed );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-1582")
|
||||||
|
public void testPostCommitDeleteListenerRollback() {
|
||||||
|
Session session = openSession();
|
||||||
|
Transaction transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
IrrelevantEntity irrelevantEntity = new IrrelevantEntity();
|
||||||
|
irrelevantEntity.setName( "Irrelevant" );
|
||||||
|
|
||||||
|
session.save( irrelevantEntity );
|
||||||
|
session.flush();
|
||||||
|
transaction.commit();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
session = openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
session.delete( irrelevantEntity );
|
||||||
|
session.flush();
|
||||||
|
transaction.rollback();
|
||||||
|
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
Assert.assertEquals( 0, ((TestPostCommitDeleteEventListener) postCommitDeleteEventListener).success );
|
||||||
|
Assert.assertEquals( 1, ((TestPostCommitDeleteEventListener) postCommitDeleteEventListener).failed );
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestPostCommitDeleteEventListener implements PostCommitDeleteEventListener {
|
||||||
|
int success;
|
||||||
|
int failed;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPostDelete(PostDeleteEvent event) {
|
||||||
|
success++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPostDeleteCommitFailed(PostDeleteEvent event) {
|
||||||
|
failed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresPostCommitHanding(EntityPersister persister) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestPostCommitUpdateEventListener implements PostCommitUpdateEventListener {
|
||||||
|
int sucess;
|
||||||
|
int failed;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPostUpdate(PostUpdateEvent event) {
|
||||||
|
sucess++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPostUpdateCommitFailed(PostUpdateEvent event) {
|
||||||
|
failed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresPostCommitHanding(EntityPersister persister) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestPostCommitInsertEventListener implements PostCommitInsertEventListener {
|
||||||
|
int success;
|
||||||
|
int failed;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPostInsert(PostInsertEvent event) {
|
||||||
|
success++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPostInsertCommitFailed(PostInsertEvent event) {
|
||||||
|
failed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresPostCommitHanding(EntityPersister persister) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class[] {IrrelevantEntity.class};
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue