HHH-8577 - ClearListener: allow to listen for clear events
This commit is contained in:
parent
3d366a526e
commit
b20ac395cb
|
@ -55,6 +55,7 @@ import org.hibernate.event.service.spi.EventListenerRegistry;
|
|||
import org.hibernate.event.spi.EventType;
|
||||
|
||||
import static org.hibernate.event.spi.EventType.AUTO_FLUSH;
|
||||
import static org.hibernate.event.spi.EventType.CLEAR;
|
||||
import static org.hibernate.event.spi.EventType.DELETE;
|
||||
import static org.hibernate.event.spi.EventType.DIRTY_CHECK;
|
||||
import static org.hibernate.event.spi.EventType.EVICT;
|
||||
|
@ -226,6 +227,11 @@ public class EventListenerRegistryImpl implements EventListenerRegistry {
|
|||
workMap
|
||||
);
|
||||
|
||||
prepareListeners(
|
||||
CLEAR,
|
||||
workMap
|
||||
);
|
||||
|
||||
// flush listeners
|
||||
prepareListeners(
|
||||
FLUSH,
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.event.spi;
|
||||
|
||||
/**
|
||||
* An event for {@link org.hibernate.Session#clear()} listening
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ClearEvent extends AbstractEvent {
|
||||
/**
|
||||
* Constructs an event from the given event session.
|
||||
*
|
||||
* @param source The session event source.
|
||||
*/
|
||||
public ClearEvent(EventSource source) {
|
||||
super( source );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.event.spi;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Listener for notification of {@link org.hibernate.Session#clear()}
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ClearEventListener extends Serializable {
|
||||
/**
|
||||
* Callback for {@link org.hibernate.Session#clear()} notification
|
||||
*
|
||||
* @param event The event representing the clear
|
||||
*/
|
||||
public void onClear(ClearEvent event);
|
||||
}
|
|
@ -38,90 +38,61 @@ import org.hibernate.HibernateException;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EventType<T> {
|
||||
public static final EventType<LoadEventListener> LOAD
|
||||
= new EventType<LoadEventListener>( "load", LoadEventListener.class );
|
||||
public static final EventType<ResolveNaturalIdEventListener> RESOLVE_NATURAL_ID
|
||||
= new EventType<ResolveNaturalIdEventListener>( "resolve-natural-id", ResolveNaturalIdEventListener.class );
|
||||
public static final EventType<InitializeCollectionEventListener> INIT_COLLECTION
|
||||
= new EventType<InitializeCollectionEventListener>( "load-collection", InitializeCollectionEventListener.class );
|
||||
public static final EventType<LoadEventListener> LOAD = create( "load", LoadEventListener.class );
|
||||
public static final EventType<ResolveNaturalIdEventListener> RESOLVE_NATURAL_ID = create( "resolve-natural-id", ResolveNaturalIdEventListener.class );
|
||||
|
||||
public static final EventType<SaveOrUpdateEventListener> SAVE_UPDATE
|
||||
= new EventType<SaveOrUpdateEventListener>( "save-update", SaveOrUpdateEventListener.class );
|
||||
public static final EventType<SaveOrUpdateEventListener> UPDATE
|
||||
= new EventType<SaveOrUpdateEventListener>( "update", SaveOrUpdateEventListener.class );
|
||||
public static final EventType<SaveOrUpdateEventListener> SAVE
|
||||
= new EventType<SaveOrUpdateEventListener>( "save", SaveOrUpdateEventListener.class );
|
||||
public static final EventType<PersistEventListener> PERSIST
|
||||
= new EventType<PersistEventListener>( "create", PersistEventListener.class );
|
||||
public static final EventType<PersistEventListener> PERSIST_ONFLUSH
|
||||
= new EventType<PersistEventListener>( "create-onflush", PersistEventListener.class );
|
||||
public static final EventType<InitializeCollectionEventListener> INIT_COLLECTION = create( "load-collection", InitializeCollectionEventListener.class );
|
||||
|
||||
public static final EventType<MergeEventListener> MERGE
|
||||
= new EventType<MergeEventListener>( "merge", MergeEventListener.class );
|
||||
public static final EventType<SaveOrUpdateEventListener> SAVE_UPDATE = create( "save-update", SaveOrUpdateEventListener.class );
|
||||
public static final EventType<SaveOrUpdateEventListener> UPDATE = create( "update", SaveOrUpdateEventListener.class );
|
||||
public static final EventType<SaveOrUpdateEventListener> SAVE = create( "save", SaveOrUpdateEventListener.class );
|
||||
public static final EventType<PersistEventListener> PERSIST = create( "create", PersistEventListener.class );
|
||||
public static final EventType<PersistEventListener> PERSIST_ONFLUSH = create( "create-onflush", PersistEventListener.class );
|
||||
|
||||
public static final EventType<DeleteEventListener> DELETE
|
||||
= new EventType<DeleteEventListener>( "delete", DeleteEventListener.class );
|
||||
public static final EventType<MergeEventListener> MERGE = create( "merge", MergeEventListener.class );
|
||||
|
||||
public static final EventType<ReplicateEventListener> REPLICATE
|
||||
= new EventType<ReplicateEventListener>( "replicate", ReplicateEventListener.class );
|
||||
public static final EventType<DeleteEventListener> DELETE = create( "delete", DeleteEventListener.class );
|
||||
|
||||
public static final EventType<FlushEventListener> FLUSH
|
||||
= new EventType<FlushEventListener>( "flush", FlushEventListener.class );
|
||||
public static final EventType<AutoFlushEventListener> AUTO_FLUSH
|
||||
= new EventType<AutoFlushEventListener>( "auto-flush", AutoFlushEventListener.class );
|
||||
public static final EventType<DirtyCheckEventListener> DIRTY_CHECK
|
||||
= new EventType<DirtyCheckEventListener>( "dirty-check", DirtyCheckEventListener.class );
|
||||
public static final EventType<FlushEntityEventListener> FLUSH_ENTITY
|
||||
= new EventType<FlushEntityEventListener>( "flush-entity", FlushEntityEventListener.class );
|
||||
public static final EventType<ReplicateEventListener> REPLICATE = create( "replicate", ReplicateEventListener.class );
|
||||
|
||||
public static final EventType<EvictEventListener> EVICT
|
||||
= new EventType<EvictEventListener>( "evict", EvictEventListener.class );
|
||||
public static final EventType<FlushEventListener> FLUSH = create( "flush", FlushEventListener.class );
|
||||
public static final EventType<AutoFlushEventListener> AUTO_FLUSH = create( "auto-flush", AutoFlushEventListener.class );
|
||||
public static final EventType<DirtyCheckEventListener> DIRTY_CHECK = create( "dirty-check", DirtyCheckEventListener.class );
|
||||
public static final EventType<FlushEntityEventListener> FLUSH_ENTITY = create( "flush-entity", FlushEntityEventListener.class );
|
||||
|
||||
public static final EventType<LockEventListener> LOCK
|
||||
= new EventType<LockEventListener>( "lock", LockEventListener.class );
|
||||
public static final EventType<ClearEventListener> CLEAR = create( "clear", ClearEventListener.class );
|
||||
public static final EventType<EvictEventListener> EVICT = create( "evict", EvictEventListener.class );
|
||||
|
||||
public static final EventType<RefreshEventListener> REFRESH
|
||||
= new EventType<RefreshEventListener>( "refresh", RefreshEventListener.class );
|
||||
public static final EventType<LockEventListener> LOCK = create( "lock", LockEventListener.class );
|
||||
|
||||
public static final EventType<PreLoadEventListener> PRE_LOAD
|
||||
= new EventType<PreLoadEventListener>( "pre-load", PreLoadEventListener.class );
|
||||
public static final EventType<PreDeleteEventListener> PRE_DELETE
|
||||
= new EventType<PreDeleteEventListener>( "pre-delete", PreDeleteEventListener.class );
|
||||
public static final EventType<PreUpdateEventListener> PRE_UPDATE
|
||||
= new EventType<PreUpdateEventListener>( "pre-update", PreUpdateEventListener.class );
|
||||
public static final EventType<PreInsertEventListener> PRE_INSERT
|
||||
= new EventType<PreInsertEventListener>( "pre-insert", PreInsertEventListener.class );
|
||||
public static final EventType<RefreshEventListener> REFRESH = create( "refresh", RefreshEventListener.class );
|
||||
|
||||
public static final EventType<PostLoadEventListener> POST_LOAD
|
||||
= new EventType<PostLoadEventListener>( "post-load", PostLoadEventListener.class );
|
||||
public static final EventType<PostDeleteEventListener> POST_DELETE
|
||||
= new EventType<PostDeleteEventListener>( "post-delete", PostDeleteEventListener.class );
|
||||
public static final EventType<PostUpdateEventListener> POST_UPDATE
|
||||
= new EventType<PostUpdateEventListener>( "post-update", PostUpdateEventListener.class );
|
||||
public static final EventType<PostInsertEventListener> POST_INSERT
|
||||
= new EventType<PostInsertEventListener>( "post-insert", PostInsertEventListener.class );
|
||||
public static final EventType<PreLoadEventListener> PRE_LOAD = create( "pre-load", PreLoadEventListener.class );
|
||||
public static final EventType<PreDeleteEventListener> PRE_DELETE = create( "pre-delete", PreDeleteEventListener.class );
|
||||
public static final EventType<PreUpdateEventListener> PRE_UPDATE = create( "pre-update", PreUpdateEventListener.class );
|
||||
public static final EventType<PreInsertEventListener> PRE_INSERT = create( "pre-insert", PreInsertEventListener.class );
|
||||
|
||||
public static final EventType<PostDeleteEventListener> POST_COMMIT_DELETE
|
||||
= new EventType<PostDeleteEventListener>( "post-commit-delete", PostDeleteEventListener.class );
|
||||
public static final EventType<PostUpdateEventListener> POST_COMMIT_UPDATE
|
||||
= new EventType<PostUpdateEventListener>( "post-commit-update", PostUpdateEventListener.class );
|
||||
public static final EventType<PostInsertEventListener> POST_COMMIT_INSERT
|
||||
= new EventType<PostInsertEventListener>( "post-commit-insert", PostInsertEventListener.class );
|
||||
public static final EventType<PostLoadEventListener> POST_LOAD = create( "post-load", PostLoadEventListener.class );
|
||||
public static final EventType<PostDeleteEventListener> POST_DELETE = create( "post-delete", PostDeleteEventListener.class );
|
||||
public static final EventType<PostUpdateEventListener> POST_UPDATE = create( "post-update", PostUpdateEventListener.class );
|
||||
public static final EventType<PostInsertEventListener> POST_INSERT = create( "post-insert", PostInsertEventListener.class );
|
||||
|
||||
public static final EventType<PreCollectionRecreateEventListener> PRE_COLLECTION_RECREATE
|
||||
= new EventType<PreCollectionRecreateEventListener>( "pre-collection-recreate", PreCollectionRecreateEventListener.class );
|
||||
public static final EventType<PreCollectionRemoveEventListener> PRE_COLLECTION_REMOVE
|
||||
= new EventType<PreCollectionRemoveEventListener>( "pre-collection-remove", PreCollectionRemoveEventListener.class );
|
||||
public static final EventType<PreCollectionUpdateEventListener> PRE_COLLECTION_UPDATE
|
||||
= new EventType<PreCollectionUpdateEventListener>( "pre-collection-update", PreCollectionUpdateEventListener.class );
|
||||
public static final EventType<PostDeleteEventListener> POST_COMMIT_DELETE = create( "post-commit-delete", PostDeleteEventListener.class );
|
||||
public static final EventType<PostUpdateEventListener> POST_COMMIT_UPDATE = create( "post-commit-update", PostUpdateEventListener.class );
|
||||
public static final EventType<PostInsertEventListener> POST_COMMIT_INSERT = create( "post-commit-insert", PostInsertEventListener.class );
|
||||
|
||||
public static final EventType<PostCollectionRecreateEventListener> POST_COLLECTION_RECREATE
|
||||
= new EventType<PostCollectionRecreateEventListener>( "post-collection-recreate", PostCollectionRecreateEventListener.class );
|
||||
public static final EventType<PostCollectionRemoveEventListener> POST_COLLECTION_REMOVE
|
||||
= new EventType<PostCollectionRemoveEventListener>( "post-collection-remove", PostCollectionRemoveEventListener.class );
|
||||
public static final EventType<PostCollectionUpdateEventListener> POST_COLLECTION_UPDATE
|
||||
= new EventType<PostCollectionUpdateEventListener>( "post-collection-update", PostCollectionUpdateEventListener.class );
|
||||
public static final EventType<PreCollectionRecreateEventListener> PRE_COLLECTION_RECREATE = create( "pre-collection-recreate", PreCollectionRecreateEventListener.class );
|
||||
public static final EventType<PreCollectionRemoveEventListener> PRE_COLLECTION_REMOVE = create( "pre-collection-remove", PreCollectionRemoveEventListener.class );
|
||||
public static final EventType<PreCollectionUpdateEventListener> PRE_COLLECTION_UPDATE = create( "pre-collection-update", PreCollectionUpdateEventListener.class );
|
||||
|
||||
public static final EventType<PostCollectionRecreateEventListener> POST_COLLECTION_RECREATE = create( "post-collection-recreate", PostCollectionRecreateEventListener.class );
|
||||
public static final EventType<PostCollectionRemoveEventListener> POST_COLLECTION_REMOVE = create( "post-collection-remove", PostCollectionRemoveEventListener.class );
|
||||
public static final EventType<PostCollectionUpdateEventListener> POST_COLLECTION_UPDATE = create( "post-collection-update", PostCollectionUpdateEventListener.class );
|
||||
|
||||
|
||||
private static <T> EventType<T> create(String name, Class<T> listenerClass) {
|
||||
return new EventType<T>( name, listenerClass );
|
||||
}
|
||||
|
||||
/**
|
||||
* Maintain a map of {@link EventType} instances keyed by name for lookup by name as well as {@link #values()}
|
||||
|
@ -132,14 +103,13 @@ public class EventType<T> {
|
|||
@Override
|
||||
public Map<String, EventType> run() {
|
||||
final Map<String, EventType> typeByNameMap = new HashMap<String, EventType>();
|
||||
final Field[] fields = EventType.class.getDeclaredFields();
|
||||
for ( int i = 0, max = fields.length; i < max; i++ ) {
|
||||
if ( EventType.class.isAssignableFrom( fields[i].getType() ) ) {
|
||||
for ( Field field : EventType.class.getDeclaredFields() ) {
|
||||
if ( EventType.class.isAssignableFrom( field.getType() ) ) {
|
||||
try {
|
||||
final EventType typeField = ( EventType ) fields[i].get( null );
|
||||
final EventType typeField = (EventType) field.get( null );
|
||||
typeByNameMap.put( typeField.eventName(), typeField );
|
||||
}
|
||||
catch( Exception t ) {
|
||||
catch (Exception t) {
|
||||
throw new HibernateException( "Unable to initialize EventType map", t );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,6 +109,8 @@ import org.hibernate.event.service.spi.EventListenerGroup;
|
|||
import org.hibernate.event.service.spi.EventListenerRegistry;
|
||||
import org.hibernate.event.spi.AutoFlushEvent;
|
||||
import org.hibernate.event.spi.AutoFlushEventListener;
|
||||
import org.hibernate.event.spi.ClearEvent;
|
||||
import org.hibernate.event.spi.ClearEventListener;
|
||||
import org.hibernate.event.spi.DeleteEvent;
|
||||
import org.hibernate.event.spi.DeleteEventListener;
|
||||
import org.hibernate.event.spi.DirtyCheckEvent;
|
||||
|
@ -332,6 +334,11 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
private void internalClear() {
|
||||
persistenceContext.clear();
|
||||
actionQueue.clear();
|
||||
|
||||
final ClearEvent event = new ClearEvent( this );
|
||||
for ( ClearEventListener listener : listeners( EventType.CLEAR ) ) {
|
||||
listener.onClear( event );
|
||||
}
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.test.events;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.event.service.spi.EventListenerRegistry;
|
||||
import org.hibernate.event.spi.ClearEvent;
|
||||
import org.hibernate.event.spi.ClearEventListener;
|
||||
import org.hibernate.event.spi.EventType;
|
||||
import org.hibernate.integrator.spi.Integrator;
|
||||
import org.hibernate.metamodel.source.MetadataImplementor;
|
||||
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ClearEventListenerTest extends BaseCoreFunctionalTestCase {
|
||||
@Test
|
||||
public void testExplicitClear() {
|
||||
listener.callCount = 0;
|
||||
|
||||
Session s = openSession();
|
||||
s.clear();
|
||||
assertEquals( 1, listener.callCount );
|
||||
s.close();
|
||||
assertEquals( 1, listener.callCount );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAutoClear() {
|
||||
listener.callCount = 0;
|
||||
|
||||
Session s = openSession();
|
||||
( (SessionImplementor) s ).setAutoClear( true );
|
||||
s.beginTransaction();
|
||||
assertEquals( 0, listener.callCount );
|
||||
s.getTransaction().commit();
|
||||
assertEquals( 1, listener.callCount );
|
||||
s.close();
|
||||
assertEquals( 1, listener.callCount );
|
||||
}
|
||||
|
||||
private TheListener listener = new TheListener();
|
||||
|
||||
private static class TheListener implements ClearEventListener {
|
||||
private int callCount;
|
||||
|
||||
@Override
|
||||
public void onClear(ClearEvent event) {
|
||||
callCount++;
|
||||
}
|
||||
}
|
||||
|
||||
@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 ).setListeners(
|
||||
EventType.CLEAR,
|
||||
listener
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disintegrate(
|
||||
SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue