HHH-5913 - Implement set of event listeners as a service

This commit is contained in:
Steve Ebersole 2011-03-21 08:55:33 -05:00
parent 478e10ae3a
commit 5adf2960c2
78 changed files with 3160 additions and 1800 deletions

View File

@ -33,9 +33,13 @@ import org.hibernate.cache.CacheKey;
import org.hibernate.cache.access.SoftLock;
import org.hibernate.collection.PersistentCollection;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.event.EventSource;
import org.hibernate.event.EventType;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.service.event.spi.EventListenerGroup;
import org.hibernate.service.event.spi.EventListenerRegistry;
/**
* Any action relating to insert/update/delete of a collection
@ -191,6 +195,18 @@ public abstract class CollectionAction implements Executable, Serializable, Comp
persister.getCacheAccessStrategy().unlockItem( ck, lock );
}
}
protected <T> EventListenerGroup<T> listenerGroup(EventType<T> eventType) {
return getSession()
.getFactory()
.getServiceRegistry()
.getService( EventListenerRegistry.class )
.getEventListenerGroup( eventType );
}
protected EventSource eventSource() {
return (EventSource) getSession();
}
}

View File

@ -29,12 +29,13 @@ import org.hibernate.HibernateException;
import org.hibernate.cache.CacheException;
import org.hibernate.collection.PersistentCollection;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.event.EventSource;
import org.hibernate.event.EventType;
import org.hibernate.event.PostCollectionRecreateEvent;
import org.hibernate.event.PostCollectionRecreateEventListener;
import org.hibernate.event.PreCollectionRecreateEvent;
import org.hibernate.event.PreCollectionRecreateEventListener;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.service.event.spi.EventListenerGroup;
public final class CollectionRecreateAction extends CollectionAction {
@ -71,26 +72,24 @@ public final class CollectionRecreateAction extends CollectionAction {
}
private void preRecreate() {
PreCollectionRecreateEventListener[] preListeners = getSession().getListeners()
.getPreCollectionRecreateEventListeners();
if (preListeners.length > 0) {
PreCollectionRecreateEvent preEvent = new PreCollectionRecreateEvent(
getPersister(), getCollection(), ( EventSource ) getSession() );
for ( PreCollectionRecreateEventListener preListener : preListeners ) {
preListener.onPreRecreateCollection( preEvent );
EventListenerGroup<PreCollectionRecreateEventListener> listenerGroup = listenerGroup( EventType.PRE_COLLECTION_RECREATE );
if ( listenerGroup.isEmpty() ) {
return;
}
final PreCollectionRecreateEvent event = new PreCollectionRecreateEvent( getPersister(), getCollection(), eventSource() );
for ( PreCollectionRecreateEventListener listener : listenerGroup.listeners() ) {
listener.onPreRecreateCollection( event );
}
}
private void postRecreate() {
PostCollectionRecreateEventListener[] postListeners = getSession().getListeners()
.getPostCollectionRecreateEventListeners();
if (postListeners.length > 0) {
PostCollectionRecreateEvent postEvent = new PostCollectionRecreateEvent(
getPersister(), getCollection(), ( EventSource ) getSession() );
for ( PostCollectionRecreateEventListener postListener : postListeners ) {
postListener.onPostRecreateCollection( postEvent );
}
EventListenerGroup<PostCollectionRecreateEventListener> listenerGroup = listenerGroup( EventType.POST_COLLECTION_RECREATE );
if ( listenerGroup.isEmpty() ) {
return;
}
final PostCollectionRecreateEvent event = new PostCollectionRecreateEvent( getPersister(), getCollection(), eventSource() );
for ( PostCollectionRecreateEventListener listener : listenerGroup.listeners() ) {
listener.onPostRecreateCollection( event );
}
}
}

View File

@ -29,12 +29,13 @@ import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
import org.hibernate.collection.PersistentCollection;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.event.EventSource;
import org.hibernate.event.EventType;
import org.hibernate.event.PostCollectionRemoveEvent;
import org.hibernate.event.PostCollectionRemoveEventListener;
import org.hibernate.event.PreCollectionRemoveEvent;
import org.hibernate.event.PreCollectionRemoveEventListener;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.service.event.spi.EventListenerGroup;
public final class CollectionRemoveAction extends CollectionAction {
@ -128,26 +129,34 @@ public final class CollectionRemoveAction extends CollectionAction {
}
private void preRemove() {
PreCollectionRemoveEventListener[] preListeners = getSession().getListeners()
.getPreCollectionRemoveEventListeners();
if (preListeners.length>0) {
PreCollectionRemoveEvent preEvent = new PreCollectionRemoveEvent(
getPersister(), getCollection(), ( EventSource ) getSession(), affectedOwner );
for ( PreCollectionRemoveEventListener preListener : preListeners ) {
preListener.onPreRemoveCollection( preEvent );
EventListenerGroup<PreCollectionRemoveEventListener> listenerGroup = listenerGroup( EventType.PRE_COLLECTION_REMOVE );
if ( listenerGroup.isEmpty() ) {
return;
}
final PreCollectionRemoveEvent event = new PreCollectionRemoveEvent(
getPersister(),
getCollection(),
eventSource(),
affectedOwner
);
for ( PreCollectionRemoveEventListener listener : listenerGroup.listeners() ) {
listener.onPreRemoveCollection( event );
}
}
private void postRemove() {
PostCollectionRemoveEventListener[] postListeners = getSession().getListeners()
.getPostCollectionRemoveEventListeners();
if (postListeners.length>0) {
PostCollectionRemoveEvent postEvent = new PostCollectionRemoveEvent(
getPersister(), getCollection(), ( EventSource ) getSession(), affectedOwner );
for ( PostCollectionRemoveEventListener postListener : postListeners ) {
postListener.onPostRemoveCollection( postEvent );
}
EventListenerGroup<PostCollectionRemoveEventListener> listenerGroup = listenerGroup( EventType.POST_COLLECTION_REMOVE );
if ( listenerGroup.isEmpty() ) {
return;
}
final PostCollectionRemoveEvent event = new PostCollectionRemoveEvent(
getPersister(),
getCollection(),
eventSource(),
affectedOwner
);
for ( PostCollectionRemoveEventListener listener : listenerGroup.listeners() ) {
listener.onPostRemoveCollection( event );
}
}
}

View File

@ -30,12 +30,16 @@ import org.hibernate.HibernateException;
import org.hibernate.collection.PersistentCollection;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.event.EventSource;
import org.hibernate.event.EventType;
import org.hibernate.event.PostCollectionUpdateEvent;
import org.hibernate.event.PostCollectionUpdateEventListener;
import org.hibernate.event.PreCollectionRemoveEvent;
import org.hibernate.event.PreCollectionRemoveEventListener;
import org.hibernate.event.PreCollectionUpdateEvent;
import org.hibernate.event.PreCollectionUpdateEventListener;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.service.event.spi.EventListenerGroup;
public final class CollectionUpdateAction extends CollectionAction {
@ -99,29 +103,32 @@ public final class CollectionUpdateAction extends CollectionAction {
}
private void preUpdate() {
PreCollectionUpdateEventListener[] preListeners = getSession().getListeners()
.getPreCollectionUpdateEventListeners();
if (preListeners.length > 0) {
PreCollectionUpdateEvent preEvent = new PreCollectionUpdateEvent(
getPersister(), getCollection(), ( EventSource ) getSession() );
for ( PreCollectionUpdateEventListener preListener : preListeners ) {
preListener.onPreUpdateCollection( preEvent );
EventListenerGroup<PreCollectionUpdateEventListener> listenerGroup = listenerGroup( EventType.PRE_COLLECTION_UPDATE );
if ( listenerGroup.isEmpty() ) {
return;
}
final PreCollectionUpdateEvent event = new PreCollectionUpdateEvent(
getPersister(),
getCollection(),
eventSource()
);
for ( PreCollectionUpdateEventListener listener : listenerGroup.listeners() ) {
listener.onPreUpdateCollection( event );
}
}
private void postUpdate() {
PostCollectionUpdateEventListener[] postListeners = getSession().getListeners()
.getPostCollectionUpdateEventListeners();
if (postListeners.length > 0) {
PostCollectionUpdateEvent postEvent = new PostCollectionUpdateEvent(
EventListenerGroup<PostCollectionUpdateEventListener> listenerGroup = listenerGroup( EventType.POST_COLLECTION_UPDATE );
if ( listenerGroup.isEmpty() ) {
return;
}
final PostCollectionUpdateEvent event = new PostCollectionUpdateEvent(
getPersister(),
getCollection(),
( EventSource ) getSession()
eventSource()
);
for ( PostCollectionUpdateEventListener postListener : postListeners ) {
postListener.onPostUpdateCollection( postEvent );
}
for ( PostCollectionUpdateEventListener listener : listenerGroup.listeners() ) {
listener.onPostUpdateCollection( event );
}
}
}

View File

@ -30,9 +30,13 @@ import org.hibernate.action.spi.AfterTransactionCompletionProcess;
import org.hibernate.action.spi.BeforeTransactionCompletionProcess;
import org.hibernate.action.spi.Executable;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.event.EventSource;
import org.hibernate.event.EventType;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.service.event.spi.EventListenerGroup;
import org.hibernate.service.event.spi.EventListenerRegistry;
/**
* Base class for actions relating to insert/update/delete of an entity
@ -185,5 +189,17 @@ public abstract class EntityAction
this.instance = session.getPersistenceContext().getEntity( session.generateEntityKey( id, persister ) );
}
}
protected <T> EventListenerGroup<T> listenerGroup(EventType<T> eventType) {
return getSession()
.getFactory()
.getServiceRegistry()
.getService( EventListenerRegistry.class )
.getEventListenerGroup( eventType );
}
protected EventSource eventSource() {
return (EventSource) getSession();
}
}

View File

@ -33,11 +33,13 @@ import org.hibernate.engine.EntityEntry;
import org.hibernate.engine.PersistenceContext;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.event.EventSource;
import org.hibernate.event.EventType;
import org.hibernate.event.PostDeleteEvent;
import org.hibernate.event.PostDeleteEventListener;
import org.hibernate.event.PreDeleteEvent;
import org.hibernate.event.PreDeleteEventListener;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.service.event.spi.EventListenerGroup;
public final class EntityDeleteAction extends EntityAction {
private final Object version;
@ -116,49 +118,47 @@ public final class EntityDeleteAction extends EntityAction {
}
private boolean preDelete() {
PreDeleteEventListener[] preListeners = getSession().getListeners().getPreDeleteEventListeners();
boolean veto = false;
if (preListeners.length>0) {
PreDeleteEvent preEvent = new PreDeleteEvent( getInstance(), getId(), state, getPersister() ,(EventSource) getSession() );
for ( PreDeleteEventListener preListener : preListeners ) {
veto = preListener.onPreDelete( preEvent ) || veto;
EventListenerGroup<PreDeleteEventListener> listenerGroup = listenerGroup( EventType.PRE_DELETE );
if ( listenerGroup.isEmpty() ) {
return veto;
}
final PreDeleteEvent event = new PreDeleteEvent( getInstance(), getId(), state, getPersister(), eventSource() );
for ( PreDeleteEventListener listener : listenerGroup.listeners() ) {
veto |= listener.onPreDelete( event );
}
return veto;
}
private void postDelete() {
PostDeleteEventListener[] postListeners = getSession().getListeners()
.getPostDeleteEventListeners();
if (postListeners.length>0) {
PostDeleteEvent postEvent = new PostDeleteEvent(
EventListenerGroup<PostDeleteEventListener> listenerGroup = listenerGroup( EventType.POST_DELETE );
if ( listenerGroup.isEmpty() ) {
return;
}
final PostDeleteEvent event = new PostDeleteEvent(
getInstance(),
getId(),
state,
getPersister(),
(EventSource) getSession()
eventSource()
);
for ( PostDeleteEventListener postListener : postListeners ) {
postListener.onPostDelete( postEvent );
}
for ( PostDeleteEventListener listener : listenerGroup.listeners() ) {
listener.onPostDelete( event );
}
}
private void postCommitDelete() {
PostDeleteEventListener[] postListeners = getSession().getListeners()
.getPostCommitDeleteEventListeners();
if (postListeners.length>0) {
PostDeleteEvent postEvent = new PostDeleteEvent(
EventListenerGroup<PostDeleteEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_DELETE );
if ( listenerGroup.isEmpty() ) {
return;
}
final PostDeleteEvent event = new PostDeleteEvent(
getInstance(),
getId(),
state,
getPersister(),
(EventSource) getSession()
eventSource()
);
for ( PostDeleteEventListener postListener : postListeners ) {
postListener.onPostDelete( postEvent );
}
}
}
@Override
@ -176,6 +176,6 @@ public final class EntityDeleteAction extends EntityAction {
@Override
protected boolean hasPostCommitEventListeners() {
return getSession().getListeners().getPostCommitDeleteEventListeners().length > 0;
return ! listenerGroup( EventType.POST_COMMIT_DELETE ).isEmpty();
}
}

View File

@ -30,12 +30,13 @@ import org.hibernate.HibernateException;
import org.hibernate.engine.EntityEntry;
import org.hibernate.engine.EntityKey;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.event.EventSource;
import org.hibernate.event.EventType;
import org.hibernate.event.PostInsertEvent;
import org.hibernate.event.PostInsertEventListener;
import org.hibernate.event.PreInsertEvent;
import org.hibernate.event.PreInsertEventListener;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.service.event.spi.EventListenerGroup;
public final class EntityIdentityInsertAction extends EntityAction {
@ -109,7 +110,7 @@ public final class EntityIdentityInsertAction extends EntityAction {
@Override
protected boolean hasPostCommitEventListeners() {
return getSession().getListeners().getPostCommitInsertEventListeners().length>0;
return ! listenerGroup( EventType.POST_COMMIT_INSERT ).isEmpty();
}
@Override
@ -126,48 +127,49 @@ public final class EntityIdentityInsertAction extends EntityAction {
if ( isDelayed ) {
getSession().getPersistenceContext().replaceDelayedEntityIdentityInsertKeys( delayedEntityKey, generatedId );
}
PostInsertEventListener[] postListeners = getSession().getListeners()
.getPostInsertEventListeners();
if (postListeners.length>0) {
PostInsertEvent postEvent = new PostInsertEvent(
EventListenerGroup<PostInsertEventListener> listenerGroup = listenerGroup( EventType.POST_INSERT );
if ( listenerGroup.isEmpty() ) {
return;
}
final PostInsertEvent event = new PostInsertEvent(
getInstance(),
generatedId,
state,
getPersister(),
(EventSource) getSession()
eventSource()
);
for ( PostInsertEventListener postListener : postListeners ) {
postListener.onPostInsert( postEvent );
}
for ( PostInsertEventListener listener : listenerGroup.listeners() ) {
listener.onPostInsert( event );
}
}
private void postCommitInsert() {
PostInsertEventListener[] postListeners = getSession().getListeners()
.getPostCommitInsertEventListeners();
if (postListeners.length>0) {
PostInsertEvent postEvent = new PostInsertEvent(
EventListenerGroup<PostInsertEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_INSERT );
if ( listenerGroup.isEmpty() ) {
return;
}
final PostInsertEvent event = new PostInsertEvent(
getInstance(),
generatedId,
state,
getPersister(),
(EventSource) getSession()
eventSource()
);
for ( PostInsertEventListener postListener : postListeners ) {
postListener.onPostInsert( postEvent );
}
for ( PostInsertEventListener listener : listenerGroup.listeners() ) {
listener.onPostInsert( event );
}
}
private boolean preInsert() {
PreInsertEventListener[] preListeners = getSession().getListeners()
.getPreInsertEventListeners();
boolean veto = false;
if (preListeners.length>0) {
PreInsertEvent preEvent = new PreInsertEvent( getInstance(), null, state, getPersister(), (EventSource)getSession() );
for ( PreInsertEventListener preListener : preListeners ) {
veto = preListener.onPreInsert( preEvent ) || veto;
EventListenerGroup<PreInsertEventListener> listenerGroup = listenerGroup( EventType.PRE_INSERT );
if ( listenerGroup.isEmpty() ) {
return false; // NO_VETO
}
boolean veto = false;
final PreInsertEvent event = new PreInsertEvent( getInstance(), null, state, getPersister(), eventSource() );
for ( PreInsertEventListener listener : listenerGroup.listeners() ) {
veto |= listener.onPreInsert( event );
}
return veto;
}

View File

@ -34,11 +34,14 @@ import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.Versioning;
import org.hibernate.event.EventSource;
import org.hibernate.event.EventType;
import org.hibernate.event.PostInsertEvent;
import org.hibernate.event.PostInsertEventListener;
import org.hibernate.event.PreInsertEvent;
import org.hibernate.event.PreInsertEventListener;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.service.event.spi.EventListenerGroup;
import org.hibernate.service.event.spi.EventListenerRegistry;
public final class EntityInsertAction extends EntityAction {
@ -129,48 +132,49 @@ public final class EntityInsertAction extends EntityAction {
}
private void postInsert() {
PostInsertEventListener[] postListeners = getSession().getListeners()
.getPostInsertEventListeners();
if ( postListeners.length > 0 ) {
PostInsertEvent postEvent = new PostInsertEvent(
EventListenerGroup<PostInsertEventListener> listenerGroup = listenerGroup( EventType.POST_INSERT );
if ( listenerGroup.isEmpty() ) {
return;
}
final PostInsertEvent event = new PostInsertEvent(
getInstance(),
getId(),
state,
getPersister(),
(EventSource) getSession()
eventSource()
);
for ( int i = 0; i < postListeners.length; i++ ) {
postListeners[i].onPostInsert(postEvent);
}
for ( PostInsertEventListener listener : listenerGroup.listeners() ) {
listener.onPostInsert( event );
}
}
private void postCommitInsert() {
PostInsertEventListener[] postListeners = getSession().getListeners()
.getPostCommitInsertEventListeners();
if ( postListeners.length > 0 ) {
PostInsertEvent postEvent = new PostInsertEvent(
EventListenerGroup<PostInsertEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_INSERT );
if ( listenerGroup.isEmpty() ) {
return;
}
final PostInsertEvent event = new PostInsertEvent(
getInstance(),
getId(),
state,
getPersister(),
(EventSource) getSession()
eventSource()
);
for ( PostInsertEventListener postListener : postListeners ) {
postListener.onPostInsert( postEvent );
}
for ( PostInsertEventListener listener : listenerGroup.listeners() ) {
listener.onPostInsert( event );
}
}
private boolean preInsert() {
PreInsertEventListener[] preListeners = getSession().getListeners()
.getPreInsertEventListeners();
boolean veto = false;
if (preListeners.length>0) {
PreInsertEvent preEvent = new PreInsertEvent( getInstance(), getId(), state, getPersister(), (EventSource)getSession() );
for ( PreInsertEventListener preListener : preListeners ) {
veto = preListener.onPreInsert( preEvent ) || veto;
EventListenerGroup<PreInsertEventListener> listenerGroup = listenerGroup( EventType.PRE_INSERT );
if ( listenerGroup.isEmpty() ) {
return veto;
}
final PreInsertEvent event = new PreInsertEvent( getInstance(), getId(), state, getPersister(), eventSource() );
for ( PreInsertEventListener listener : listenerGroup.listeners() ) {
veto |= listener.onPreInsert( event );
}
return veto;
}
@ -192,7 +196,7 @@ public final class EntityInsertAction extends EntityAction {
@Override
protected boolean hasPostCommitEventListeners() {
return getSession().getListeners().getPostCommitInsertEventListeners().length>0;
return ! listenerGroup( EventType.POST_COMMIT_INSERT ).isEmpty();
}
private boolean isCachePutEnabled(EntityPersister persister, SessionImplementor session) {

View File

@ -36,12 +36,13 @@ import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.Status;
import org.hibernate.engine.Versioning;
import org.hibernate.event.EventSource;
import org.hibernate.event.EventType;
import org.hibernate.event.PostUpdateEvent;
import org.hibernate.event.PostUpdateEventListener;
import org.hibernate.event.PreUpdateEvent;
import org.hibernate.event.PreUpdateEventListener;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.service.event.spi.EventListenerGroup;
import org.hibernate.type.TypeHelper;
public final class EntityUpdateAction extends EntityAction {
@ -181,67 +182,67 @@ public final class EntityUpdateAction extends EntityAction {
}
}
private void postUpdate() {
PostUpdateEventListener[] postListeners = getSession().getListeners()
.getPostUpdateEventListeners();
if (postListeners.length>0) {
PostUpdateEvent postEvent = new PostUpdateEvent(
getInstance(),
getId(),
state,
previousState,
dirtyFields,
getPersister(),
(EventSource) getSession()
);
for ( int i = 0; i < postListeners.length; i++ ) {
postListeners[i].onPostUpdate(postEvent);
}
}
}
private void postCommitUpdate() {
PostUpdateEventListener[] postListeners = getSession().getListeners()
.getPostCommitUpdateEventListeners();
if (postListeners.length>0) {
PostUpdateEvent postEvent = new PostUpdateEvent(
getInstance(),
getId(),
state,
previousState,
dirtyFields,
getPersister(),
(EventSource) getSession()
);
for ( int i = 0; i < postListeners.length; i++ ) {
postListeners[i].onPostUpdate(postEvent);
}
}
}
private boolean preUpdate() {
PreUpdateEventListener[] preListeners = getSession().getListeners()
.getPreUpdateEventListeners();
boolean veto = false;
if (preListeners.length>0) {
PreUpdateEvent preEvent = new PreUpdateEvent(
EventListenerGroup<PreUpdateEventListener> listenerGroup = listenerGroup( EventType.PRE_UPDATE );
if ( listenerGroup.isEmpty() ) {
return veto;
}
final PreUpdateEvent event = new PreUpdateEvent(
getInstance(),
getId(),
state,
previousState,
getPersister(),
(EventSource)getSession()
eventSource()
);
for ( int i = 0; i < preListeners.length; i++ ) {
veto = preListeners[i].onPreUpdate(preEvent) || veto;
}
for ( PreUpdateEventListener listener : listenerGroup.listeners() ) {
veto |= listener.onPreUpdate( event );
}
return veto;
}
private void postUpdate() {
EventListenerGroup<PostUpdateEventListener> listenerGroup = listenerGroup( EventType.POST_UPDATE );
if ( listenerGroup.isEmpty() ) {
return;
}
final PostUpdateEvent event = new PostUpdateEvent(
getInstance(),
getId(),
state,
previousState,
dirtyFields,
getPersister(),
eventSource()
);
for ( PostUpdateEventListener listener : listenerGroup.listeners() ) {
listener.onPostUpdate( event );
}
}
private void postCommitUpdate() {
EventListenerGroup<PostUpdateEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_UPDATE );
if ( listenerGroup.isEmpty() ) {
return;
}
final PostUpdateEvent event = new PostUpdateEvent(
getInstance(),
getId(),
state,
previousState,
dirtyFields,
getPersister(),
eventSource()
);
for ( PostUpdateEventListener listener : listenerGroup.listeners() ) {
listener.onPostUpdate( event );
}
}
@Override
protected boolean hasPostCommitEventListeners() {
return getSession().getListeners().getPostCommitUpdateEventListeners().length>0;
return ! listenerGroup( EventType.POST_COMMIT_UPDATE ).isEmpty();
}
@Override

View File

@ -22,17 +22,22 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.cache.entry;
import java.io.Serializable;
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.event.EventSource;
import org.hibernate.event.EventType;
import org.hibernate.event.PreLoadEvent;
import org.hibernate.event.PreLoadEventListener;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.TypeHelper;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.service.event.spi.EventListenerGroup;
import org.hibernate.service.event.spi.EventListenerRegistry;
import org.hibernate.type.TypeHelper;
/**
* A cached instance of a persistent class
@ -121,14 +126,18 @@ public final class CacheEntry implements Serializable {
//persister.setIdentifier(result, id); //before calling interceptor, for consistency with normal load
//TODO: reuse the PreLoadEvent
PreLoadEvent preLoadEvent = new PreLoadEvent( session )
final PreLoadEvent preLoadEvent = new PreLoadEvent( session )
.setEntity( result )
.setState( assembledProps )
.setId( id )
.setPersister( persister );
PreLoadEventListener[] listeners = session.getListeners().getPreLoadEventListeners();
for ( PreLoadEventListener listener : listeners ) {
final EventListenerGroup<PreLoadEventListener> listenerGroup = session
.getFactory()
.getServiceRegistry()
.getService( EventListenerRegistry.class )
.getEventListenerGroup( EventType.PRE_LOAD );
for ( PreLoadEventListener listener : listenerGroup.listeners() ) {
listener.onPreLoad( preLoadEvent );
}

View File

@ -93,6 +93,7 @@ import org.hibernate.event.AutoFlushEventListener;
import org.hibernate.event.DeleteEventListener;
import org.hibernate.event.DirtyCheckEventListener;
import org.hibernate.event.EventListeners;
import org.hibernate.event.EventType;
import org.hibernate.event.EvictEventListener;
import org.hibernate.event.FlushEntityEventListener;
import org.hibernate.event.FlushEventListener;
@ -159,8 +160,15 @@ import org.hibernate.mapping.TypeDef;
import org.hibernate.mapping.UniqueKey;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.secure.JACCConfiguration;
<<<<<<< HEAD
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.internal.BasicServiceRegistryImpl;
=======
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.event.spi.EventListenerRegistry;
import org.hibernate.service.internal.ServiceRegistryImpl;
import org.hibernate.service.spi.ServiceRegistry;
>>>>>>> HHH-5913 - Implement set of event listeners as a service
import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
import org.hibernate.tool.hbm2ddl.IndexMetadata;
import org.hibernate.tool.hbm2ddl.TableMetadata;
@ -261,8 +269,6 @@ public class Configuration implements Serializable {
protected NamingStrategy namingStrategy;
private SessionFactoryObserver sessionFactoryObserver;
private EventListeners eventListeners;
protected final SettingsFactory settingsFactory;
private transient Mapping mapping = buildMapping();
@ -330,7 +336,6 @@ public class Configuration implements Serializable {
interceptor = EmptyInterceptor.INSTANCE;
properties = Environment.getProperties();
entityResolver = XMLHelper.DEFAULT_DTD_RESOLVER;
eventListeners = new EventListeners();
sqlFunctions = new HashMap<String, SQLFunction>();
@ -1813,9 +1818,10 @@ public class Configuration implements Serializable {
secondPassCompile();
if (!metadataSourceQueue.isEmpty()) LOG.incompleteMappingMetadataCacheProcessing();
enableLegacyHibernateValidator();
enableBeanValidation();
enableHibernateSearch();
// todo : processing listeners for validator and search (and envers) requires HHH-5562
enableLegacyHibernateValidator( serviceRegistry );
enableBeanValidation( serviceRegistry );
// enableHibernateSearch();
validate();
Environment.verifyProperties( properties );
@ -1829,7 +1835,6 @@ public class Configuration implements Serializable {
mapping,
serviceRegistry,
settings,
getInitializedEventListeners(),
sessionFactoryObserver
);
}
@ -1866,82 +1871,42 @@ public class Configuration implements Serializable {
private static final String LEGACY_VALIDATOR_EVENT_LISTENER = "org.hibernate.validator.event.ValidateEventListener";
private void enableLegacyHibernateValidator() {
//add validator events if the jar is available
boolean enableValidatorListeners = !"false".equalsIgnoreCase(
getProperty(
"hibernate.validator.autoregister_listeners"
)
);
private void enableLegacyHibernateValidator(ServiceRegistry serviceRegistry) {
boolean loadLegacyValidator = ConfigurationHelper.getBoolean( "hibernate.validator.autoregister_listeners", properties, false );
Class validateEventListenerClass = null;
try {
validateEventListenerClass = ReflectHelper.classForName( LEGACY_VALIDATOR_EVENT_LISTENER, Configuration.class );
validateEventListenerClass = serviceRegistry.getService( ClassLoaderService.class ).classForName( LEGACY_VALIDATOR_EVENT_LISTENER );
}
catch ( ClassNotFoundException e ) {
//validator is not present
LOG.debugf("Legacy Validator not present in classpath, ignoring event listener registration");
catch ( Exception ignored) {
}
if ( enableValidatorListeners && validateEventListenerClass != null ) {
//TODO so much duplication
Object validateEventListener;
if ( ! loadLegacyValidator || validateEventListenerClass == null) {
LOG.debugf( "Skipping legacy validator loading" );
return;
}
final Object validateEventListener;
try {
validateEventListener = validateEventListenerClass.newInstance();
}
catch ( Exception e ) {
throw new AnnotationException( "Unable to load Validator event listener", e );
}
{
boolean present = false;
PreInsertEventListener[] listeners = getEventListeners().getPreInsertEventListeners();
if ( listeners != null ) {
for ( Object eventListener : listeners ) {
//not isAssignableFrom since the user could subclass
present = present || validateEventListenerClass == eventListener.getClass();
}
if ( !present ) {
int length = listeners.length + 1;
PreInsertEventListener[] newListeners = new PreInsertEventListener[length];
System.arraycopy( listeners, 0, newListeners, 0, length - 1 );
newListeners[length - 1] = ( PreInsertEventListener ) validateEventListener;
getEventListeners().setPreInsertEventListeners( newListeners );
}
}
else {
getEventListeners().setPreInsertEventListeners(
new PreInsertEventListener[] { ( PreInsertEventListener ) validateEventListener }
);
}
EventListenerRegistry listenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );
// todo : duplication strategy
listenerRegistry.appendListeners( EventType.PRE_INSERT, (PreInsertEventListener) validateEventListener );
listenerRegistry.appendListeners( EventType.PRE_UPDATE, (PreUpdateEventListener) validateEventListener );
}
//update event listener
{
boolean present = false;
PreUpdateEventListener[] listeners = getEventListeners().getPreUpdateEventListeners();
if ( listeners != null ) {
for ( Object eventListener : listeners ) {
//not isAssignableFrom since the user could subclass
present = present || validateEventListenerClass == eventListener.getClass();
}
if ( !present ) {
int length = listeners.length + 1;
PreUpdateEventListener[] newListeners = new PreUpdateEventListener[length];
System.arraycopy( listeners, 0, newListeners, 0, length - 1 );
newListeners[length - 1] = ( PreUpdateEventListener ) validateEventListener;
getEventListeners().setPreUpdateEventListeners( newListeners );
}
}
else {
getEventListeners().setPreUpdateEventListeners(
new PreUpdateEventListener[] { ( PreUpdateEventListener ) validateEventListener }
private void enableBeanValidation(ServiceRegistry serviceRegistry) {
BeanValidationActivator.activateBeanValidation(
serviceRegistry.getService( EventListenerRegistry.class ),
getProperties()
);
}
}
}
}
private void enableBeanValidation() {
BeanValidationActivator.activateBeanValidation( getEventListeners(), getProperties() );
}
private static final String SEARCH_EVENT_LISTENER_REGISTERER_CLASS = "org.hibernate.cfg.search.HibernateSearchEventListenerRegister";
@ -1949,53 +1914,47 @@ public class Configuration implements Serializable {
* Tries to automatically register Hibernate Search event listeners by locating the
* appropriate bootstrap class and calling the <code>enableHibernateSearch</code> method.
*/
private void enableHibernateSearch() {
// load the bootstrap class
Class searchStartupClass;
try {
searchStartupClass = ReflectHelper.classForName( SEARCH_STARTUP_CLASS, getClass() );
}
catch ( ClassNotFoundException e ) {
// TODO remove this together with SearchConfiguration after 3.1.0 release of Search
// try loading deprecated HibernateSearchEventListenerRegister
try {
searchStartupClass = ReflectHelper.classForName( SEARCH_EVENT_LISTENER_REGISTERER_CLASS, getClass() );
}
catch ( ClassNotFoundException cnfe ) {
LOG.debugf("Search not present in classpath, ignoring event listener registration.");
return;
}
}
// call the method for registering the listeners
try {
Object searchStartupInstance = searchStartupClass.newInstance();
Method enableSearchMethod = searchStartupClass.getDeclaredMethod(
SEARCH_STARTUP_METHOD,
EventListeners.class,
Properties.class
);
enableSearchMethod.invoke( searchStartupInstance, getEventListeners(), getProperties() );
}
catch ( InstantiationException e ) {
LOG.debugf("Unable to instantiate %s, ignoring event listener registration.", SEARCH_STARTUP_CLASS);
}
catch ( IllegalAccessException e ) {
LOG.debugf("Unable to instantiate %s, ignoring event listener registration.", SEARCH_STARTUP_CLASS);
}
catch ( NoSuchMethodException e ) {
LOG.debugf("Method %s() not found in %s", SEARCH_STARTUP_METHOD, SEARCH_STARTUP_CLASS);
}
catch ( InvocationTargetException e ) {
LOG.debugf("Unable to execute %s, ignoring event listener registration.", SEARCH_STARTUP_METHOD);
}
}
private EventListeners getInitializedEventListeners() {
EventListeners result = (EventListeners) eventListeners.shallowCopy();
result.initializeListeners( this );
return result;
}
// private void enableHibernateSearch() {
// // load the bootstrap class
// Class searchStartupClass;
// try {
// searchStartupClass = ReflectHelper.classForName( SEARCH_STARTUP_CLASS, getClass() );
// }
// catch ( ClassNotFoundException e ) {
// // TODO remove this together with SearchConfiguration after 3.1.0 release of Search
// // try loading deprecated HibernateSearchEventListenerRegister
// try {
// searchStartupClass = ReflectHelper.classForName( SEARCH_EVENT_LISTENER_REGISTERER_CLASS, getClass() );
// }
// catch ( ClassNotFoundException cnfe ) {
// LOG.debugf("Search not present in classpath, ignoring event listener registration.");
// return;
// }
// }
//
// // call the method for registering the listeners
// try {
// Object searchStartupInstance = searchStartupClass.newInstance();
// Method enableSearchMethod = searchStartupClass.getDeclaredMethod(
// SEARCH_STARTUP_METHOD,
// EventListeners.class,
// Properties.class
// );
// enableSearchMethod.invoke( searchStartupInstance, getEventListeners(), getProperties() );
// }
// catch ( InstantiationException e ) {
// LOG.debugf("Unable to instantiate %s, ignoring event listener registration.", SEARCH_STARTUP_CLASS);
// }
// catch ( IllegalAccessException e ) {
// LOG.debugf("Unable to instantiate %s, ignoring event listener registration.", SEARCH_STARTUP_CLASS);
// }
// catch ( NoSuchMethodException e ) {
// LOG.debugf("Method %s() not found in %s", SEARCH_STARTUP_METHOD, SEARCH_STARTUP_CLASS);
// }
// catch ( InvocationTargetException e ) {
// LOG.debugf("Unable to execute %s, ignoring event listener registration.", SEARCH_STARTUP_METHOD);
// }
// }
/**
* Rterieve the configured {@link Interceptor}.
@ -2308,12 +2267,6 @@ public class Configuration implements Serializable {
final String region = ( regionNode == null ) ? role : regionNode.getValue();
setCollectionCacheConcurrencyStrategy( role, subelement.attributeValue( "usage" ), region );
}
else if ( "listener".equals( subelementName ) ) {
parseListener( subelement );
}
else if ( "event".equals( subelementName ) ) {
parseEvent( subelement );
}
}
}
@ -2381,356 +2334,6 @@ public class Configuration implements Serializable {
}
}
private void parseEvent(Element element) {
String type = element.attributeValue( "type" );
List listeners = element.elements();
String[] listenerClasses = new String[ listeners.size() ];
for ( int i = 0; i < listeners.size() ; i++ ) {
listenerClasses[i] = ( (Element) listeners.get( i ) ).attributeValue( "class" );
}
LOG.debugf("Event listeners: %s=%s", type, StringHelper.toString(listenerClasses));
setListeners( type, listenerClasses );
}
private void parseListener(Element element) {
String type = element.attributeValue( "type" );
if ( type == null ) {
throw new MappingException( "No type specified for listener" );
}
String impl = element.attributeValue( "class" );
LOG.debugf("Event listener: %s=%s", type, impl);
setListeners( type, new String[]{impl} );
}
public void setListener(String type, String listener) {
String[] listeners = null;
if ( listener != null ) {
listeners = (String[]) Array.newInstance( String.class, 1 );
listeners[0] = listener;
}
setListeners( type, listeners );
}
public void setListeners(String type, String[] listenerClasses) {
Object[] listeners = null;
if ( listenerClasses != null ) {
listeners = (Object[]) Array.newInstance( eventListeners.getListenerClassFor(type), listenerClasses.length );
for ( int i = 0; i < listeners.length ; i++ ) {
try {
listeners[i] = ReflectHelper.classForName( listenerClasses[i] ).newInstance();
}
catch (Exception e) {
throw new MappingException(
"Unable to instantiate specified event (" + type + ") listener class: " + listenerClasses[i],
e
);
}
}
}
setListeners( type, listeners );
}
public void setListener(String type, Object listener) {
Object[] listeners = null;
if ( listener != null ) {
listeners = (Object[]) Array.newInstance( eventListeners.getListenerClassFor(type), 1 );
listeners[0] = listener;
}
setListeners( type, listeners );
}
public void setListeners(String type, Object[] listeners) {
if ( "auto-flush".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setAutoFlushEventListeners( new AutoFlushEventListener[]{} );
}
else {
eventListeners.setAutoFlushEventListeners( (AutoFlushEventListener[]) listeners );
}
}
else if ( "merge".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setMergeEventListeners( new MergeEventListener[]{} );
}
else {
eventListeners.setMergeEventListeners( (MergeEventListener[]) listeners );
}
}
else if ( "create".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPersistEventListeners( new PersistEventListener[]{} );
}
else {
eventListeners.setPersistEventListeners( (PersistEventListener[]) listeners );
}
}
else if ( "create-onflush".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPersistOnFlushEventListeners( new PersistEventListener[]{} );
}
else {
eventListeners.setPersistOnFlushEventListeners( (PersistEventListener[]) listeners );
}
}
else if ( "delete".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setDeleteEventListeners( new DeleteEventListener[]{} );
}
else {
eventListeners.setDeleteEventListeners( (DeleteEventListener[]) listeners );
}
}
else if ( "dirty-check".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setDirtyCheckEventListeners( new DirtyCheckEventListener[]{} );
}
else {
eventListeners.setDirtyCheckEventListeners( (DirtyCheckEventListener[]) listeners );
}
}
else if ( "evict".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setEvictEventListeners( new EvictEventListener[]{} );
}
else {
eventListeners.setEvictEventListeners( (EvictEventListener[]) listeners );
}
}
else if ( "flush".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setFlushEventListeners( new FlushEventListener[]{} );
}
else {
eventListeners.setFlushEventListeners( (FlushEventListener[]) listeners );
}
}
else if ( "flush-entity".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setFlushEntityEventListeners( new FlushEntityEventListener[]{} );
}
else {
eventListeners.setFlushEntityEventListeners( (FlushEntityEventListener[]) listeners );
}
}
else if ( "load".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setLoadEventListeners( new LoadEventListener[]{} );
}
else {
eventListeners.setLoadEventListeners( (LoadEventListener[]) listeners );
}
}
else if ( "load-collection".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setInitializeCollectionEventListeners(
new InitializeCollectionEventListener[]{}
);
}
else {
eventListeners.setInitializeCollectionEventListeners(
(InitializeCollectionEventListener[]) listeners
);
}
}
else if ( "lock".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setLockEventListeners( new LockEventListener[]{} );
}
else {
eventListeners.setLockEventListeners( (LockEventListener[]) listeners );
}
}
else if ( "refresh".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setRefreshEventListeners( new RefreshEventListener[]{} );
}
else {
eventListeners.setRefreshEventListeners( (RefreshEventListener[]) listeners );
}
}
else if ( "replicate".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setReplicateEventListeners( new ReplicateEventListener[]{} );
}
else {
eventListeners.setReplicateEventListeners( (ReplicateEventListener[]) listeners );
}
}
else if ( "save-update".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setSaveOrUpdateEventListeners( new SaveOrUpdateEventListener[]{} );
}
else {
eventListeners.setSaveOrUpdateEventListeners( (SaveOrUpdateEventListener[]) listeners );
}
}
else if ( "save".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setSaveEventListeners( new SaveOrUpdateEventListener[]{} );
}
else {
eventListeners.setSaveEventListeners( (SaveOrUpdateEventListener[]) listeners );
}
}
else if ( "update".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setUpdateEventListeners( new SaveOrUpdateEventListener[]{} );
}
else {
eventListeners.setUpdateEventListeners( (SaveOrUpdateEventListener[]) listeners );
}
}
else if ( "pre-load".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPreLoadEventListeners( new PreLoadEventListener[]{} );
}
else {
eventListeners.setPreLoadEventListeners( (PreLoadEventListener[]) listeners );
}
}
else if ( "pre-update".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPreUpdateEventListeners( new PreUpdateEventListener[]{} );
}
else {
eventListeners.setPreUpdateEventListeners( (PreUpdateEventListener[]) listeners );
}
}
else if ( "pre-delete".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPreDeleteEventListeners( new PreDeleteEventListener[]{} );
}
else {
eventListeners.setPreDeleteEventListeners( (PreDeleteEventListener[]) listeners );
}
}
else if ( "pre-insert".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPreInsertEventListeners( new PreInsertEventListener[]{} );
}
else {
eventListeners.setPreInsertEventListeners( (PreInsertEventListener[]) listeners );
}
}
else if ( "pre-collection-recreate".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPreCollectionRecreateEventListeners( new PreCollectionRecreateEventListener[]{} );
}
else {
eventListeners.setPreCollectionRecreateEventListeners( (PreCollectionRecreateEventListener[]) listeners );
}
}
else if ( "pre-collection-remove".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPreCollectionRemoveEventListeners( new PreCollectionRemoveEventListener[]{} );
}
else {
eventListeners.setPreCollectionRemoveEventListeners( ( PreCollectionRemoveEventListener[]) listeners );
}
}
else if ( "pre-collection-update".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPreCollectionUpdateEventListeners( new PreCollectionUpdateEventListener[]{} );
}
else {
eventListeners.setPreCollectionUpdateEventListeners( ( PreCollectionUpdateEventListener[]) listeners );
}
}
else if ( "post-load".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPostLoadEventListeners( new PostLoadEventListener[]{} );
}
else {
eventListeners.setPostLoadEventListeners( (PostLoadEventListener[]) listeners );
}
}
else if ( "post-update".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPostUpdateEventListeners( new PostUpdateEventListener[]{} );
}
else {
eventListeners.setPostUpdateEventListeners( (PostUpdateEventListener[]) listeners );
}
}
else if ( "post-delete".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPostDeleteEventListeners( new PostDeleteEventListener[]{} );
}
else {
eventListeners.setPostDeleteEventListeners( (PostDeleteEventListener[]) listeners );
}
}
else if ( "post-insert".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPostInsertEventListeners( new PostInsertEventListener[]{} );
}
else {
eventListeners.setPostInsertEventListeners( (PostInsertEventListener[]) listeners );
}
}
else if ( "post-commit-update".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPostCommitUpdateEventListeners(
new PostUpdateEventListener[]{}
);
}
else {
eventListeners.setPostCommitUpdateEventListeners( (PostUpdateEventListener[]) listeners );
}
}
else if ( "post-commit-delete".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPostCommitDeleteEventListeners(
new PostDeleteEventListener[]{}
);
}
else {
eventListeners.setPostCommitDeleteEventListeners( (PostDeleteEventListener[]) listeners );
}
}
else if ( "post-commit-insert".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPostCommitInsertEventListeners(
new PostInsertEventListener[]{}
);
}
else {
eventListeners.setPostCommitInsertEventListeners( (PostInsertEventListener[]) listeners );
}
}
else if ( "post-collection-recreate".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPostCollectionRecreateEventListeners( new PostCollectionRecreateEventListener[]{} );
}
else {
eventListeners.setPostCollectionRecreateEventListeners( (PostCollectionRecreateEventListener[]) listeners );
}
}
else if ( "post-collection-remove".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPostCollectionRemoveEventListeners( new PostCollectionRemoveEventListener[]{} );
}
else {
eventListeners.setPostCollectionRemoveEventListeners( ( PostCollectionRemoveEventListener[]) listeners );
}
}
else if ( "post-collection-update".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPostCollectionUpdateEventListeners( new PostCollectionUpdateEventListener[]{} );
}
else {
eventListeners.setPostCollectionUpdateEventListeners( ( PostCollectionUpdateEventListener[]) listeners );
}
}
else {
throw new MappingException("Unrecognized listener type [" + type + "]");
}
}
public EventListeners getEventListeners() {
return eventListeners;
}
RootClass getRootClassMapping(String clazz) throws MappingException {
try {
return (RootClass) getClassMapping( clazz );

View File

@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* Copyright (c) 2011, 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 Middleware LLC.
* 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
@ -20,7 +20,6 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.cfg;
@ -30,7 +29,7 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.config.ConfigurationHelper;
/**
@ -41,7 +40,6 @@ import org.hibernate.internal.util.config.ConfigurationHelper;
* @author Steve Ebersole
*/
public abstract class ExternalSessionFactoryConfig {
private String mapResources;
private String dialect;
private String defaultSchema;
@ -66,8 +64,6 @@ public abstract class ExternalSessionFactoryConfig {
private Map additionalProperties;
private Set excludedPropertyNames = new HashSet();
private Map customListeners;
protected Set getExcludedPropertyNames() {
return excludedPropertyNames;
@ -253,37 +249,6 @@ public abstract class ExternalSessionFactoryConfig {
this.queryCacheEnabled = queryCacheEnabled;
}
public final Map getCustomListeners() {
return customListeners;
}
public void setCustomListeners(Map customListeners) {
this.customListeners = customListeners;
}
public void setCustomListenersAsString(String customListenersString) {
// Note : expected in the syntax:
// type=listenerClass
// ({sep}type=listenerClass)*
// where {sep} is any whitespace or comma
if ( StringHelper.isNotEmpty( customListenersString ) ) {
String[] listenerEntries = ConfigurationHelper.toStringArray( customListenersString, " ,\n\t\r\f" );
for ( int i = 0; i < listenerEntries.length; i++ ) {
final int keyValueSepPosition = listenerEntries[i].indexOf( '=' );
final String type = listenerEntries[i].substring( 0, keyValueSepPosition );
final String listenerClass = listenerEntries[i].substring( keyValueSepPosition + 1 );
setCustomListener( type, listenerClass );
}
}
}
public void setCustomListener(String type, String listenerClass) {
if ( customListeners == null ) {
customListeners = new HashMap();
}
customListeners.put( type, listenerClass );
}
public final void addAdditionalProperty(String name, String value) {
if ( !getExcludedPropertyNames().contains( name ) ) {
if ( additionalProperties == null ) {
@ -303,25 +268,6 @@ public abstract class ExternalSessionFactoryConfig {
cfg.addResource( mappingFiles[i] );
}
if ( customListeners != null && !customListeners.isEmpty() ) {
Iterator entries = customListeners.entrySet().iterator();
while ( entries.hasNext() ) {
final Map.Entry entry = ( Map.Entry ) entries.next();
final String type = ( String ) entry.getKey();
final Object value = entry.getValue();
if ( value != null ) {
if ( String.class.isAssignableFrom( value.getClass() ) ) {
// Its the listener class name
cfg.setListener( type, ( ( String ) value ) );
}
else {
// Its the listener instance (or better be)
cfg.setListener( type, value );
}
}
}
}
return cfg;
}

View File

@ -22,17 +22,20 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.cfg.beanvalidation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.cfg.Environment;
import org.hibernate.event.EventListeners;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.service.event.spi.EventListenerRegistry;
/**
* This class has no hard dependency on Bean Validation APIs
@ -40,14 +43,13 @@ import org.hibernate.mapping.PersistentClass;
* @author Emmanuel Bernard
*/
public class BeanValidationActivator {
private static final String BV_DISCOVERY_CLASS = "javax.validation.Validation";
private static final String TYPE_SAFE_ACTIVATOR_CLASS = "org.hibernate.cfg.beanvalidation.TypeSafeActivator";
private static final String TYPE_SAFE_DDL_METHOD = "applyDDL";
private static final String TYPE_SAFE_ACTIVATOR_METHOD = "activateBeanValidation";
private static final String MODE_PROPERTY = "javax.persistence.validation.mode";
public static void activateBeanValidation(EventListeners eventListeners, Properties properties) {
public static void activateBeanValidation(EventListenerRegistry listenerRegistry, Properties properties) {
Set<ValidationMode> modes = ValidationMode.getModes( properties.get( MODE_PROPERTY ) );
try {
@ -76,8 +78,8 @@ public class BeanValidationActivator {
try {
Class<?> activator = ReflectHelper.classForName( TYPE_SAFE_ACTIVATOR_CLASS, BeanValidationActivator.class );
Method activateBeanValidation =
activator.getMethod( TYPE_SAFE_ACTIVATOR_METHOD, EventListeners.class, Properties.class );
activateBeanValidation.invoke( null, eventListeners, properties );
activator.getMethod( TYPE_SAFE_ACTIVATOR_METHOD, EventListenerRegistry.class, Properties.class );
activateBeanValidation.invoke( null, listenerRegistry, properties );
}
catch ( NoSuchMethodException e ) {
throw new HibernateException( "Unable to get the default Bean Validation factory", e);

View File

@ -0,0 +1,44 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.cfg.beanvalidation;
import org.hibernate.service.event.spi.DuplicationStrategy;
/**
* @author Steve Ebersole
*/
public class DuplicationStrategyImpl implements DuplicationStrategy {
public static final DuplicationStrategyImpl INSTANCE = new DuplicationStrategyImpl();
@Override
public boolean areMatch(Object listener, Object original) {
return listener.getClass().equals( original.getClass() ) &&
BeanValidationEventListener.class.equals( listener.getClass() );
}
@Override
public Action getAction() {
return Action.KEEP_ORIGINAL;
}
}

View File

@ -23,15 +23,6 @@
*/
package org.hibernate.cfg.beanvalidation;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;
import javax.validation.constraints.Digits;
@ -42,14 +33,23 @@ import javax.validation.constraints.Size;
import javax.validation.metadata.BeanDescriptor;
import javax.validation.metadata.ConstraintDescriptor;
import javax.validation.metadata.PropertyDescriptor;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import org.jboss.logging.Logger;
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
import org.hibernate.HibernateLogger;
import org.hibernate.MappingException;
import org.hibernate.event.EventListeners;
import org.hibernate.event.PreDeleteEventListener;
import org.hibernate.event.PreInsertEventListener;
import org.hibernate.event.PreUpdateEventListener;
import org.hibernate.event.EventType;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.Column;
@ -57,7 +57,7 @@ import org.hibernate.mapping.Component;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.SingleTableSubclass;
import org.jboss.logging.Logger;
import org.hibernate.service.event.spi.EventListenerRegistry;
/**
* @author Emmanuel Bernard
@ -69,40 +69,21 @@ class TypeSafeActivator {
private static final String FACTORY_PROPERTY = "javax.persistence.validation.factory";
public static void activateBeanValidation(EventListeners eventListeners, Properties properties) {
@SuppressWarnings( {"UnusedDeclaration"})
public static void activateBeanValidation(EventListenerRegistry listenerRegistry, Properties properties) {
ValidatorFactory factory = getValidatorFactory( properties );
BeanValidationEventListener beanValidationEventListener = new BeanValidationEventListener(
BeanValidationEventListener listener = new BeanValidationEventListener(
factory, properties
);
{
PreInsertEventListener[] listeners = eventListeners.getPreInsertEventListeners();
int length = listeners.length + 1;
PreInsertEventListener[] newListeners = new PreInsertEventListener[length];
System.arraycopy( listeners, 0, newListeners, 0, length - 1 );
newListeners[length - 1] = beanValidationEventListener;
eventListeners.setPreInsertEventListeners( newListeners );
}
{
PreUpdateEventListener[] listeners = eventListeners.getPreUpdateEventListeners();
int length = listeners.length + 1;
PreUpdateEventListener[] newListeners = new PreUpdateEventListener[length];
System.arraycopy( listeners, 0, newListeners, 0, length - 1 );
newListeners[length - 1] = beanValidationEventListener;
eventListeners.setPreUpdateEventListeners( newListeners );
}
{
PreDeleteEventListener[] listeners = eventListeners.getPreDeleteEventListeners();
int length = listeners.length + 1;
PreDeleteEventListener[] newListeners = new PreDeleteEventListener[length];
System.arraycopy( listeners, 0, newListeners, 0, length - 1 );
newListeners[length - 1] = beanValidationEventListener;
eventListeners.setPreDeleteEventListeners( newListeners );
}
listenerRegistry.addDuplicationStrategy( DuplicationStrategyImpl.INSTANCE );
listenerRegistry.appendListeners( EventType.PRE_INSERT, listener );
listenerRegistry.appendListeners( EventType.PRE_UPDATE, listener );
listenerRegistry.appendListeners( EventType.PRE_DELETE, listener );
}
@SuppressWarnings( {"UnusedDeclaration"})
public static void applyDDL(Collection<PersistentClass> persistentClasses, Properties properties) {
ValidatorFactory factory = getValidatorFactory( properties );
Class<?>[] groupsArray = new GroupsPerOperation( properties ).get( GroupsPerOperation.Operation.DDL );

View File

@ -288,13 +288,6 @@ public interface SessionImplementor extends Serializable, LobCreationContext {
public int getDontFlushFromFind();
/**
* Retrieves the configured event listeners from this event source.
*
* @return The configured event listeners.
*/
public EventListeners getListeners();
//TODO: temporary
/**

View File

@ -35,6 +35,7 @@ import org.hibernate.LockMode;
import org.hibernate.bytecode.instrumentation.spi.LazyPropertyInitializer;
import org.hibernate.cache.CacheKey;
import org.hibernate.cache.entry.CacheEntry;
import org.hibernate.event.EventType;
import org.hibernate.event.PostLoadEvent;
import org.hibernate.event.PostLoadEventListener;
import org.hibernate.event.PreLoadEvent;
@ -43,6 +44,8 @@ import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.property.BackrefPropertyAccessor;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.service.event.spi.EventListenerGroup;
import org.hibernate.service.event.spi.EventListenerRegistry;
import org.hibernate.type.Type;
import org.hibernate.type.TypeHelper;
@ -55,7 +58,9 @@ import org.hibernate.type.TypeHelper;
*/
public final class TwoPhaseLoad {
private static final HibernateLogger LOG = Logger.getMessageLogger(HibernateLogger.class, TwoPhaseLoad.class.getName());
private static final HibernateLogger LOG = Logger.getMessageLogger(
HibernateLogger.class, TwoPhaseLoad.class.getName()
);
private TwoPhaseLoad() {}
@ -127,8 +132,10 @@ public final class TwoPhaseLoad {
Serializable id = entityEntry.getId();
Object[] hydratedState = entityEntry.getLoadedState();
if (LOG.isDebugEnabled()) LOG.debugf("Resolving associations for %s",
MessageHelper.infoString(persister, id, session.getFactory()));
if (LOG.isDebugEnabled()) LOG.debugf(
"Resolving associations for %s",
MessageHelper.infoString( persister, id, session.getFactory() )
);
Type[] types = persister.getPropertyTypes();
for ( int i = 0; i < hydratedState.length; i++ ) {
@ -141,9 +148,14 @@ public final class TwoPhaseLoad {
//Must occur after resolving identifiers!
if ( session.isEventSource() ) {
preLoadEvent.setEntity( entity ).setState( hydratedState ).setId( id ).setPersister( persister );
PreLoadEventListener[] listeners = session.getListeners().getPreLoadEventListeners();
for ( int i = 0; i < listeners.length; i++ ) {
listeners[i].onPreLoad(preLoadEvent);
final EventListenerGroup<PreLoadEventListener> listenerGroup = session
.getFactory()
.getServiceRegistry()
.getService( EventListenerRegistry.class )
.getEventListenerGroup( EventType.PRE_LOAD );
for ( PreLoadEventListener listener : listenerGroup.listeners() ) {
listener.onPreLoad( preLoadEvent );
}
}
@ -152,8 +164,10 @@ public final class TwoPhaseLoad {
final SessionFactoryImplementor factory = session.getFactory();
if ( persister.hasCache() && session.getCacheMode().isPutEnabled() ) {
if (LOG.isDebugEnabled()) LOG.debugf("Adding entity to second-level cache: %s",
MessageHelper.infoString(persister, id, session.getFactory()));
if (LOG.isDebugEnabled()) LOG.debugf(
"Adding entity to second-level cache: %s",
MessageHelper.infoString( persister, id, session.getFactory() )
);
Object version = Versioning.getVersion(hydratedState, persister);
CacheEntry entry = new CacheEntry(
@ -234,14 +248,23 @@ public final class TwoPhaseLoad {
if ( session.isEventSource() ) {
postLoadEvent.setEntity( entity ).setId( id ).setPersister( persister );
PostLoadEventListener[] listeners = session.getListeners().getPostLoadEventListeners();
for ( int i = 0; i < listeners.length; i++ ) {
listeners[i].onPostLoad(postLoadEvent);
final EventListenerGroup<PostLoadEventListener> listenerGroup = session
.getFactory()
.getServiceRegistry()
.getService( EventListenerRegistry.class )
.getEventListenerGroup( EventType.POST_LOAD );
for ( PostLoadEventListener listener : listenerGroup.listeners() ) {
listener.onPostLoad( postLoadEvent );
}
}
if (LOG.isDebugEnabled()) LOG.debugf("Done materializing entity %s",
MessageHelper.infoString(persister, id, session.getFactory()));
if ( LOG.isDebugEnabled() ) {
LOG.debugf(
"Done materializing entity %s",
MessageHelper.infoString( persister, id, session.getFactory() )
);
}
if ( factory.getStatistics().isStatisticsEnabled() ) {
factory.getStatisticsImplementor().loadEntity( persister.getEntityName() );

View File

@ -0,0 +1,39 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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;
import java.util.Map;
import org.hibernate.cfg.Mappings;
import org.hibernate.service.spi.ServiceRegistry;
/**
* Contract for performing event listener registration. This is completely a work in progress for now. The
* expectation is that this gets tied in with the "service locator" pattern defined by HHH-5562
*
* @author Steve Ebersole
*/
public interface EventListenerRegistration {
public void apply(ServiceRegistry serviceRegistry, Mappings mappings, Map<?,?> configValues);
}

View File

@ -0,0 +1,195 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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;
import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.hibernate.HibernateException;
/**
* Enumeration of the recognized types of events, including meta-information about each.
*
* @author Steve Ebersole
*/
public class EventType<T> {
public static final EventType<LoadEventListener> LOAD
= new EventType<LoadEventListener>( "load", LoadEventListener.class );
public static final EventType<InitializeCollectionEventListener> INIT_COLLECTION
= new EventType<InitializeCollectionEventListener>( "load-collection", InitializeCollectionEventListener.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<MergeEventListener> MERGE
= new EventType<MergeEventListener>( "merge", MergeEventListener.class );
public static final EventType<DeleteEventListener> DELETE
= new EventType<DeleteEventListener>( "delete", DeleteEventListener.class );
public static final EventType<ReplicateEventListener> REPLICATE
= new EventType<ReplicateEventListener>( "replicate", ReplicateEventListener.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<EvictEventListener> EVICT
= new EventType<EvictEventListener>( "evict", EvictEventListener.class );
public static final EventType<LockEventListener> LOCK
= new EventType<LockEventListener>( "lock", LockEventListener.class );
public static final EventType<RefreshEventListener> REFRESH
= new EventType<RefreshEventListener>( "refresh", RefreshEventListener.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<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<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<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<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 );
/**
* Maintain a map of {@link EventType} instances keyed by name for lookup by name as well as {@link #values()}
* resolution.
*/
public static final Map<String,EventType> eventTypeByNameMap = AccessController.doPrivileged(
new PrivilegedAction<Map<String, EventType>>() {
@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() ) ) {
try {
final EventType typeField = ( EventType ) fields[i].get( null );
typeByNameMap.put( typeField.eventName(), typeField );
}
catch( Exception t ) {
throw new HibernateException( "Unable to initialize EventType map", t );
}
}
}
return typeByNameMap;
}
}
);
/**
* Find an {@link EventType} by its name
*
* @param eventName The name
*
* @return The {@link EventType} instance.
*
* @throws HibernateException If eventName is null, or if eventName does not correlate to any known event type.
*/
public static EventType resolveEventTypeByName(final String eventName) {
if ( eventName == null ) {
throw new HibernateException( "event name to resolve cannot be null" );
}
final EventType eventType = eventTypeByNameMap.get( eventName );
if ( eventType == null ) {
throw new HibernateException( "Unable to locate proper event type for event name [" + eventName + "]" );
}
return eventType;
}
/**
* Get a collection of all {@link EventType} instances.
*
* @return All {@link EventType} instances
*/
public static Collection<EventType> values() {
return eventTypeByNameMap.values();
}
private final String eventName;
private final Class<? extends T> baseListenerInterface;
private EventType(String eventName, Class<? extends T> baseListenerInterface) {
this.eventName = eventName;
this.baseListenerInterface = baseListenerInterface;
}
public String eventName() {
return eventName;
}
public Class baseListenerInterface() {
return baseListenerInterface;
}
}

View File

@ -28,6 +28,9 @@ import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.jboss.logging.Logger;
import org.hibernate.HibernateException;
import org.hibernate.HibernateLogger;
import org.hibernate.action.internal.CollectionRecreateAction;
@ -45,6 +48,7 @@ import org.hibernate.engine.PersistenceContext;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.Status;
import org.hibernate.event.EventSource;
import org.hibernate.event.EventType;
import org.hibernate.event.FlushEntityEvent;
import org.hibernate.event.FlushEntityEventListener;
import org.hibernate.event.FlushEvent;
@ -52,7 +56,8 @@ import org.hibernate.internal.util.collections.IdentityMap;
import org.hibernate.internal.util.collections.LazyIterator;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.pretty.Printer;
import org.jboss.logging.Logger;
import org.hibernate.service.event.spi.EventListenerGroup;
import org.hibernate.service.event.spi.EventListenerRegistry;
/**
* A convenience base class for listeners whose functionality results in flushing.
@ -61,8 +66,10 @@ import org.jboss.logging.Logger;
*/
public abstract class AbstractFlushingEventListener implements Serializable {
private static final HibernateLogger LOG = Logger.getMessageLogger(HibernateLogger.class,
AbstractFlushingEventListener.class.getName());
private static final HibernateLogger LOG = Logger.getMessageLogger(
HibernateLogger.class,
AbstractFlushingEventListener.class.getName()
);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Pre-flushing section
@ -105,16 +112,20 @@ public abstract class AbstractFlushingEventListener implements Serializable {
//some statistics
if (LOG.isDebugEnabled()) {
LOG.debugf("Flushed: %s insertions, %s updates, %s deletions to %s objects",
LOG.debugf(
"Flushed: %s insertions, %s updates, %s deletions to %s objects",
session.getActionQueue().numberOfInsertions(),
session.getActionQueue().numberOfUpdates(),
session.getActionQueue().numberOfDeletions(),
persistenceContext.getEntityEntries().size());
LOG.debugf("Flushed: %s (re)creations, %s updates, %s removals to %s collections",
persistenceContext.getEntityEntries().size()
);
LOG.debugf(
"Flushed: %s (re)creations, %s updates, %s removals to %s collections",
session.getActionQueue().numberOfCollectionCreations(),
session.getActionQueue().numberOfCollectionUpdates(),
session.getActionQueue().numberOfCollectionRemovals(),
persistenceContext.getCollectionEntries().size());
persistenceContext.getCollectionEntries().size()
);
new Printer( session.getFactory() ).toString(
persistenceContext.getEntitiesByKey().values().iterator(),
session.getEntityMode()
@ -211,10 +222,14 @@ public abstract class AbstractFlushingEventListener implements Serializable {
Status status = entry.getStatus();
if ( status != Status.LOADING && status != Status.GONE ) {
FlushEntityEvent entityEvent = new FlushEntityEvent( source, me.getKey(), entry );
FlushEntityEventListener[] listeners = source.getListeners().getFlushEntityEventListeners();
for ( int j = 0; j < listeners.length; j++ ) {
listeners[j].onFlushEntity(entityEvent);
final FlushEntityEvent entityEvent = new FlushEntityEvent( source, me.getKey(), entry );
final EventListenerGroup<FlushEntityEventListener> listenerGroup = source
.getFactory()
.getServiceRegistry()
.getService( EventListenerRegistry.class )
.getEventListenerGroup( EventType.FLUSH_ENTITY );
for ( FlushEntityEventListener listener : listenerGroup.listeners() ) {
listener.onFlushEntity( entityEvent );
}
}
}

View File

@ -46,6 +46,7 @@ import org.hibernate.engine.Status;
import org.hibernate.engine.TwoPhaseLoad;
import org.hibernate.engine.Versioning;
import org.hibernate.event.EventSource;
import org.hibernate.event.EventType;
import org.hibernate.event.LoadEvent;
import org.hibernate.event.LoadEventListener;
import org.hibernate.event.PostLoadEvent;
@ -54,6 +55,7 @@ import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;
import org.hibernate.service.event.spi.EventListenerRegistry;
import org.hibernate.type.EmbeddedComponentType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
@ -643,13 +645,24 @@ public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener i
//PostLoad is needed for EJB3
//TODO: reuse the PostLoadEvent...
PostLoadEvent postLoadEvent = new PostLoadEvent(session).setEntity(result)
.setId(id).setPersister(persister);
PostLoadEventListener[] listeners = session.getListeners().getPostLoadEventListeners();
for ( int i = 0; i < listeners.length; i++ ) {
listeners[i].onPostLoad(postLoadEvent);
PostLoadEvent postLoadEvent = new PostLoadEvent( session )
.setEntity( result )
.setId( id )
.setPersister( persister );
for ( PostLoadEventListener listener : postLoadEventListeners( session ) ) {
listener.onPostLoad( postLoadEvent );
}
return result;
}
private Iterable<PostLoadEventListener> postLoadEventListeners(EventSource session) {
return session
.getFactory()
.getServiceRegistry()
.getService( EventListenerRegistry.class )
.getEventListenerGroup( EventType.POST_LOAD )
.listeners();
}
}

View File

@ -192,7 +192,6 @@ public final class SessionFactoryImpl
private final transient Map<String,QueryCache> queryCaches;
private final transient ConcurrentMap<String,Region> allCacheRegions = new ConcurrentHashMap<String, Region>();
private final transient Statistics statistics;
private final transient EventListeners eventListeners;
private final transient CurrentSessionContext currentSessionContext;
private final transient EntityNotFoundDelegate entityNotFoundDelegate;
private final transient SQLFunctionRegistry sqlFunctionRegistry;
@ -210,7 +209,6 @@ public final class SessionFactoryImpl
Mapping mapping,
ServiceRegistry serviceRegistry,
Settings settings,
EventListeners listeners,
SessionFactoryObserver observer) throws HibernateException {
LOG.buildingSessionFactory();
@ -227,7 +225,6 @@ public final class SessionFactoryImpl
);
this.settings = settings;
this.sqlFunctionRegistry = new SQLFunctionRegistry( getDialect(), cfg.getSqlFunctions() );
this.eventListeners = listeners;
if ( observer != null ) {
this.observer.addObserver( observer );
}
@ -1027,7 +1024,6 @@ public final class SessionFactoryImpl
observer.sessionFactoryClosed( this );
serviceRegistry.destroy();
eventListeners.destroyListeners();
}
private class CacheImpl implements Cache {
@ -1312,10 +1308,6 @@ public final class SessionFactoryImpl
}
}
public EventListeners getEventListeners() {
return eventListeners;
}
@Override
public ServiceRegistryImplementor getServiceRegistry() {
return serviceRegistry;

View File

@ -101,8 +101,8 @@ import org.hibernate.event.DeleteEvent;
import org.hibernate.event.DeleteEventListener;
import org.hibernate.event.DirtyCheckEvent;
import org.hibernate.event.DirtyCheckEventListener;
import org.hibernate.event.EventListeners;
import org.hibernate.event.EventSource;
import org.hibernate.event.EventType;
import org.hibernate.event.EvictEvent;
import org.hibernate.event.EvictEventListener;
import org.hibernate.event.FlushEvent;
@ -138,6 +138,8 @@ import org.hibernate.persister.entity.OuterJoinLoadable;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;
import org.hibernate.service.event.spi.EventListenerGroup;
import org.hibernate.service.event.spi.EventListenerRegistry;
import org.hibernate.stat.SessionStatistics;
import org.hibernate.stat.internal.SessionStatisticsImpl;
import org.hibernate.type.SerializationException;
@ -170,7 +172,6 @@ public final class SessionImpl
private transient ActionQueue actionQueue;
private transient StatefulPersistenceContext persistenceContext;
private transient TransactionCoordinatorImpl transactionCoordinator;
private transient EventListeners listeners;
private transient Interceptor interceptor;
private transient EntityNameResolver entityNameResolver = new CoordinatingEntityNameResolver();
@ -202,7 +203,6 @@ public final class SessionImpl
this.timestamp = parent.timestamp;
this.transactionCoordinator = parent.transactionCoordinator;
this.interceptor = parent.interceptor;
this.listeners = parent.listeners;
this.actionQueue = new ActionQueue( this );
this.entityMode = entityMode;
this.persistenceContext = new StatefulPersistenceContext( this );
@ -246,7 +246,6 @@ public final class SessionImpl
this.timestamp = timestamp;
this.entityMode = entityMode;
this.interceptor = interceptor;
this.listeners = factory.getEventListeners();
this.actionQueue = new ActionQueue( this );
this.persistenceContext = new StatefulPersistenceContext( this );
this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled;
@ -684,12 +683,19 @@ public final class SessionImpl
private void fireSaveOrUpdate(SaveOrUpdateEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
SaveOrUpdateEventListener[] saveOrUpdateEventListener = listeners.getSaveOrUpdateEventListeners();
for ( int i = 0; i < saveOrUpdateEventListener.length; i++ ) {
saveOrUpdateEventListener[i].onSaveOrUpdate(event);
for ( SaveOrUpdateEventListener listener : listeners( EventType.SAVE_UPDATE ) ) {
listener.onSaveOrUpdate( event );
}
}
private <T> Iterable<T> listeners(EventType<T> type) {
return eventListenerGroup( type ).listeners();
}
private <T> EventListenerGroup<T> eventListenerGroup(EventType<T> type) {
return factory.getServiceRegistry().getService( EventListenerRegistry.class ).getEventListenerGroup( type );
}
// save() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -704,9 +710,8 @@ public final class SessionImpl
private Serializable fireSave(SaveOrUpdateEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
SaveOrUpdateEventListener[] saveEventListener = listeners.getSaveEventListeners();
for ( int i = 0; i < saveEventListener.length; i++ ) {
saveEventListener[i].onSaveOrUpdate(event);
for ( SaveOrUpdateEventListener listener : listeners( EventType.SAVE ) ) {
listener.onSaveOrUpdate( event );
}
return event.getResultId();
}
@ -725,9 +730,8 @@ public final class SessionImpl
private void fireUpdate(SaveOrUpdateEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
SaveOrUpdateEventListener[] updateEventListener = listeners.getUpdateEventListeners();
for ( int i = 0; i < updateEventListener.length; i++ ) {
updateEventListener[i].onSaveOrUpdate(event);
for ( SaveOrUpdateEventListener listener : listeners( EventType.UPDATE ) ) {
listener.onSaveOrUpdate( event );
}
}
@ -754,12 +758,11 @@ public final class SessionImpl
fireLock( new LockEvent( object, options, this ) );
}
private void fireLock(LockEvent lockEvent) {
private void fireLock(LockEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
LockEventListener[] lockEventListener = listeners.getLockEventListeners();
for ( int i = 0; i < lockEventListener.length; i++ ) {
lockEventListener[i].onLock( lockEvent );
for ( LockEventListener listener : listeners( EventType.LOCK ) ) {
listener.onLock( event );
}
}
@ -782,18 +785,16 @@ public final class SessionImpl
private void firePersist(Map copiedAlready, PersistEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
PersistEventListener[] persistEventListener = listeners.getPersistEventListeners();
for ( int i = 0; i < persistEventListener.length; i++ ) {
persistEventListener[i].onPersist(event, copiedAlready);
for ( PersistEventListener listener : listeners( EventType.PERSIST ) ) {
listener.onPersist( event, copiedAlready );
}
}
private void firePersist(PersistEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
PersistEventListener[] createEventListener = listeners.getPersistEventListeners();
for ( int i = 0; i < createEventListener.length; i++ ) {
createEventListener[i].onPersist(event);
for ( PersistEventListener listener : listeners( EventType.PERSIST ) ) {
listener.onPersist( event );
}
}
@ -817,18 +818,16 @@ public final class SessionImpl
private void firePersistOnFlush(Map copiedAlready, PersistEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
PersistEventListener[] persistEventListener = listeners.getPersistOnFlushEventListeners();
for ( int i = 0; i < persistEventListener.length; i++ ) {
persistEventListener[i].onPersist(event, copiedAlready);
for ( PersistEventListener listener : listeners( EventType.PERSIST_ONFLUSH ) ) {
listener.onPersist( event, copiedAlready );
}
}
private void firePersistOnFlush(PersistEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
PersistEventListener[] createEventListener = listeners.getPersistOnFlushEventListeners();
for ( int i = 0; i < createEventListener.length; i++ ) {
createEventListener[i].onPersist(event);
for ( PersistEventListener listener : listeners( EventType.PERSIST_ONFLUSH ) ) {
listener.onPersist( event );
}
}
@ -850,9 +849,8 @@ public final class SessionImpl
private Object fireMerge(MergeEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
MergeEventListener[] mergeEventListener = listeners.getMergeEventListeners();
for ( int i = 0; i < mergeEventListener.length; i++ ) {
mergeEventListener[i].onMerge(event);
for ( MergeEventListener listener : listeners( EventType.MERGE ) ) {
listener.onMerge( event );
}
return event.getResult();
}
@ -860,9 +858,8 @@ public final class SessionImpl
private void fireMerge(Map copiedAlready, MergeEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
MergeEventListener[] mergeEventListener = listeners.getMergeEventListeners();
for ( int i = 0; i < mergeEventListener.length; i++ ) {
mergeEventListener[i].onMerge(event, copiedAlready);
for ( MergeEventListener listener : listeners( EventType.MERGE ) ) {
listener.onMerge( event, copiedAlready );
}
}
@ -893,18 +890,16 @@ public final class SessionImpl
private void fireDelete(DeleteEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
DeleteEventListener[] deleteEventListener = listeners.getDeleteEventListeners();
for ( int i = 0; i < deleteEventListener.length; i++ ) {
deleteEventListener[i].onDelete( event );
for ( DeleteEventListener listener : listeners( EventType.DELETE ) ) {
listener.onDelete( event );
}
}
private void fireDelete(DeleteEvent event, Set transientEntities) {
errorIfClosed();
checkTransactionSynchStatus();
DeleteEventListener[] deleteEventListener = listeners.getDeleteEventListeners();
for ( int i = 0; i < deleteEventListener.length; i++ ) {
deleteEventListener[i].onDelete( event, transientEntities );
for ( DeleteEventListener listener : listeners( EventType.DELETE ) ) {
listener.onDelete( event, transientEntities );
}
}
@ -1027,9 +1022,8 @@ public final class SessionImpl
private void fireLoad(LoadEvent event, LoadType loadType) {
errorIfClosed();
checkTransactionSynchStatus();
LoadEventListener[] loadEventListener = listeners.getLoadEventListeners();
for ( int i = 0; i < loadEventListener.length; i++ ) {
loadEventListener[i].onLoad(event, loadType);
for ( LoadEventListener listener : listeners( EventType.LOAD ) ) {
listener.onLoad( event, loadType );
}
}
@ -1052,21 +1046,19 @@ public final class SessionImpl
fireRefresh( refreshedAlready, new RefreshEvent( object, this ) );
}
private void fireRefresh(RefreshEvent refreshEvent) {
private void fireRefresh(RefreshEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
RefreshEventListener[] refreshEventListener = listeners.getRefreshEventListeners();
for ( int i = 0; i < refreshEventListener.length; i++ ) {
refreshEventListener[i].onRefresh( refreshEvent );
for ( RefreshEventListener listener : listeners( EventType.REFRESH ) ) {
listener.onRefresh( event );
}
}
private void fireRefresh(Map refreshedAlready, RefreshEvent refreshEvent) {
private void fireRefresh(Map refreshedAlready, RefreshEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
RefreshEventListener[] refreshEventListener = listeners.getRefreshEventListeners();
for ( int i = 0; i < refreshEventListener.length; i++ ) {
refreshEventListener[i].onRefresh( refreshEvent, refreshedAlready );
for ( RefreshEventListener listener : listeners( EventType.REFRESH ) ) {
listener.onRefresh( event, refreshedAlready );
}
}
@ -1085,9 +1077,8 @@ public final class SessionImpl
private void fireReplicate(ReplicateEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
ReplicateEventListener[] replicateEventListener = listeners.getReplicateEventListeners();
for ( int i = 0; i < replicateEventListener.length; i++ ) {
replicateEventListener[i].onReplicate(event);
for ( ReplicateEventListener listener : listeners( EventType.REPLICATE ) ) {
listener.onReplicate( event );
}
}
@ -1102,12 +1093,11 @@ public final class SessionImpl
fireEvict( new EvictEvent( object, this ) );
}
private void fireEvict(EvictEvent evictEvent) {
private void fireEvict(EvictEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
EvictEventListener[] evictEventListener = listeners.getEvictEventListeners();
for ( int i = 0; i < evictEventListener.length; i++ ) {
evictEventListener[i].onEvict( evictEvent );
for ( EvictEventListener listener : listeners( EventType.EVICT ) ) {
listener.onEvict( event );
}
}
@ -1122,9 +1112,8 @@ public final class SessionImpl
return false;
}
AutoFlushEvent event = new AutoFlushEvent( querySpaces, this );
AutoFlushEventListener[] autoFlushEventListener = listeners.getAutoFlushEventListeners();
for ( int i = 0; i < autoFlushEventListener.length; i++ ) {
autoFlushEventListener[i].onAutoFlush(event);
for ( AutoFlushEventListener listener : listeners( EventType.AUTO_FLUSH ) ) {
listener.onAutoFlush( event );
}
return event.isFlushRequired();
}
@ -1138,9 +1127,8 @@ public final class SessionImpl
return true;
}
DirtyCheckEvent event = new DirtyCheckEvent( this );
DirtyCheckEventListener[] dirtyCheckEventListener = listeners.getDirtyCheckEventListeners();
for (int i = 0; i < dirtyCheckEventListener.length; i++) {
dirtyCheckEventListener[i].onDirtyCheck(event);
for ( DirtyCheckEventListener listener : listeners( EventType.DIRTY_CHECK ) ) {
listener.onDirtyCheck( event );
}
return event.isDirty();
}
@ -1151,9 +1139,8 @@ public final class SessionImpl
if ( persistenceContext.getCascadeLevel() > 0 ) {
throw new HibernateException("Flush during cascade is dangerous");
}
FlushEventListener[] flushEventListener = listeners.getFlushEventListeners();
for ( int i = 0; i < flushEventListener.length; i++ ) {
flushEventListener[i].onFlush( new FlushEvent(this) );
for ( FlushEventListener listener : listeners( EventType.FLUSH ) ) {
listener.onFlush( new FlushEvent( this ) );
}
}
@ -1680,9 +1667,9 @@ public final class SessionImpl
throws HibernateException {
errorIfClosed();
checkTransactionSynchStatus();
InitializeCollectionEventListener[] listener = listeners.getInitializeCollectionEventListeners();
for ( int i = 0; i < listener.length; i++ ) {
listener[i].onInitializeCollection( new InitializeCollectionEvent(collection, this) );
InitializeCollectionEvent event = new InitializeCollectionEvent( collection, this );
for ( InitializeCollectionEventListener listener : listeners( EventType.INIT_COLLECTION ) ) {
listener.onInitializeCollection( event );
}
}
@ -1762,10 +1749,6 @@ public final class SessionImpl
return buf.append(')').toString();
}
public EventListeners getListeners() {
return listeners;
}
public ActionQueue getActionQueue() {
errorIfClosed();
checkTransactionSynchStatus();
@ -1976,7 +1959,6 @@ public final class SessionImpl
interceptor = ( Interceptor ) ois.readObject();
factory = SessionFactoryImpl.deserialize( ois );
listeners = factory.getEventListeners();
if ( isRootSession ) {
transactionCoordinator = TransactionCoordinatorImpl.deserialize( ois, this );

View File

@ -445,10 +445,6 @@ public class StatelessSessionImpl extends AbstractSessionImpl implements Statele
return EmptyInterceptor.INSTANCE;
}
public EventListeners getListeners() {
throw new UnsupportedOperationException();
}
public PersistenceContext getPersistenceContext() {
return temporaryPersistenceContext;
}

View File

@ -30,6 +30,7 @@ import org.hibernate.persister.internal.PersisterClassResolverInitiator;
import org.hibernate.persister.internal.PersisterFactoryInitiator;
import org.hibernate.service.classloading.internal.ClassLoaderServiceInitiator;
import org.hibernate.service.internal.SessionFactoryServiceRegistryFactoryInitiator;
import org.hibernate.service.event.internal.EventListenerServiceInitiator;
import org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator;
import org.hibernate.service.jdbc.connections.internal.MultiTenantConnectionProviderInitiator;
import org.hibernate.service.jdbc.dialect.internal.DialectFactoryInitiator;

View File

@ -0,0 +1,179 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.service.event.internal;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
import org.hibernate.event.EventType;
import org.hibernate.service.event.spi.DuplicationStrategy;
import org.hibernate.service.event.spi.EventListenerGroup;
import org.hibernate.service.event.spi.EventListenerRegistrationException;
/**
* @author Steve Ebersole
*/
public class EventListenerGroupImpl<T> implements EventListenerGroup<T> {
private EventType<T> eventType;
private final Set<DuplicationStrategy> duplicationStrategies = new LinkedHashSet<DuplicationStrategy>();
private List<T> listeners;
public EventListenerGroupImpl(EventType<T> eventType) {
this.eventType = eventType;
duplicationStrategies.add(
// At minimum make sure we do not register the same exact listener class multiple times.
new DuplicationStrategy() {
@Override
public boolean areMatch(Object listener, Object original) {
return listener.getClass().equals( original.getClass() );
}
@Override
public Action getAction() {
return Action.ERROR;
}
}
);
}
@Override
public EventType<T> getEventType() {
return eventType;
}
@Override
public boolean isEmpty() {
return count() <= 0;
}
@Override
public int count() {
return listeners == null ? 0 : listeners.size();
}
@Override
public void clear() {
if ( duplicationStrategies != null ) {
duplicationStrategies.clear();
}
if ( listeners != null ) {
listeners.clear();
}
}
@Override
public void addDuplicationStrategy(DuplicationStrategy strategy) {
duplicationStrategies.add( strategy );
}
public Iterable<T> listeners() {
return listeners == null ? Collections.<T>emptyList() : listeners;
}
@Override
public void appendListeners(T... listeners) {
for ( T listener : listeners ) {
appendListener( listener );
}
}
@Override
public void appendListener(T listener) {
if ( listenerShouldGetAdded( listener ) ) {
internalAppend( listener );
}
}
@Override
public void prependListeners(T... listeners) {
for ( T listener : listeners ) {
prependListener( listener );
}
}
@Override
public void prependListener(T listener) {
if ( listenerShouldGetAdded( listener ) ) {
internalPrepend( listener );
}
}
private boolean listenerShouldGetAdded(T listener) {
if ( listeners == null ) {
listeners = new ArrayList<T>();
return true;
// no need to do de-dup checks
}
boolean doAdd = true;
strategy_loop: for ( DuplicationStrategy strategy : duplicationStrategies ) {
final ListIterator<T> itr = listeners.listIterator();
while ( itr.hasNext() ) {
final T existingListener = itr.next();
if ( strategy.areMatch( listener, existingListener ) ) {
switch ( strategy.getAction() ) {
// todo : add debug logging of what happens here...
case ERROR: {
throw new EventListenerRegistrationException( "Duplicate event listener found" );
}
case KEEP_ORIGINAL: {
doAdd = false;
break strategy_loop;
}
case REPLACE_ORIGINAL: {
itr.set( listener );
doAdd = false;
break strategy_loop;
}
}
}
}
}
return doAdd;
}
private void internalPrepend(T listener) {
checkAgainstBaseInterface( listener );
listeners.add( 0, listener );
}
private void checkAgainstBaseInterface(T listener) {
if ( !eventType.baseListenerInterface().isInstance( listener ) ) {
throw new EventListenerRegistrationException(
"Listener did not implement expected interface [" + eventType.baseListenerInterface().getName() + "]"
);
}
}
private void internalAppend(T listener) {
checkAgainstBaseInterface( listener );
listeners.add( listener );
}
}

View File

@ -0,0 +1,422 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.service.event.internal;
import java.lang.reflect.Array;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.hibernate.HibernateException;
import org.hibernate.event.EventType;
import org.hibernate.event.def.DefaultAutoFlushEventListener;
import org.hibernate.event.def.DefaultDeleteEventListener;
import org.hibernate.event.def.DefaultDirtyCheckEventListener;
import org.hibernate.event.def.DefaultEvictEventListener;
import org.hibernate.event.def.DefaultFlushEntityEventListener;
import org.hibernate.event.def.DefaultFlushEventListener;
import org.hibernate.event.def.DefaultInitializeCollectionEventListener;
import org.hibernate.event.def.DefaultLoadEventListener;
import org.hibernate.event.def.DefaultLockEventListener;
import org.hibernate.event.def.DefaultMergeEventListener;
import org.hibernate.event.def.DefaultPersistEventListener;
import org.hibernate.event.def.DefaultPersistOnFlushEventListener;
import org.hibernate.event.def.DefaultPostLoadEventListener;
import org.hibernate.event.def.DefaultPreLoadEventListener;
import org.hibernate.event.def.DefaultRefreshEventListener;
import org.hibernate.event.def.DefaultReplicateEventListener;
import org.hibernate.event.def.DefaultSaveEventListener;
import org.hibernate.event.def.DefaultSaveOrUpdateEventListener;
import org.hibernate.event.def.DefaultUpdateEventListener;
import org.hibernate.service.event.spi.DuplicationStrategy;
import org.hibernate.service.event.spi.EventListenerRegistrationException;
import org.hibernate.service.event.spi.EventListenerRegistry;
import static org.hibernate.event.EventType.AUTO_FLUSH;
import static org.hibernate.event.EventType.DELETE;
import static org.hibernate.event.EventType.DIRTY_CHECK;
import static org.hibernate.event.EventType.EVICT;
import static org.hibernate.event.EventType.FLUSH;
import static org.hibernate.event.EventType.FLUSH_ENTITY;
import static org.hibernate.event.EventType.INIT_COLLECTION;
import static org.hibernate.event.EventType.LOAD;
import static org.hibernate.event.EventType.LOCK;
import static org.hibernate.event.EventType.MERGE;
import static org.hibernate.event.EventType.PERSIST;
import static org.hibernate.event.EventType.PERSIST_ONFLUSH;
import static org.hibernate.event.EventType.POST_COLLECTION_RECREATE;
import static org.hibernate.event.EventType.POST_COLLECTION_REMOVE;
import static org.hibernate.event.EventType.POST_COLLECTION_UPDATE;
import static org.hibernate.event.EventType.POST_COMMIT_DELETE;
import static org.hibernate.event.EventType.POST_COMMIT_INSERT;
import static org.hibernate.event.EventType.POST_COMMIT_UPDATE;
import static org.hibernate.event.EventType.POST_DELETE;
import static org.hibernate.event.EventType.POST_INSERT;
import static org.hibernate.event.EventType.POST_LOAD;
import static org.hibernate.event.EventType.POST_UPDATE;
import static org.hibernate.event.EventType.PRE_COLLECTION_RECREATE;
import static org.hibernate.event.EventType.PRE_COLLECTION_REMOVE;
import static org.hibernate.event.EventType.PRE_COLLECTION_UPDATE;
import static org.hibernate.event.EventType.PRE_DELETE;
import static org.hibernate.event.EventType.PRE_INSERT;
import static org.hibernate.event.EventType.PRE_LOAD;
import static org.hibernate.event.EventType.PRE_UPDATE;
import static org.hibernate.event.EventType.REFRESH;
import static org.hibernate.event.EventType.REPLICATE;
import static org.hibernate.event.EventType.SAVE;
import static org.hibernate.event.EventType.SAVE_UPDATE;
import static org.hibernate.event.EventType.UPDATE;
/**
* @author Steve Ebersole
*/
public class EventListenerRegistryImpl implements EventListenerRegistry {
private Map<Class,Object> listenerClassToInstanceMap = new HashMap<Class, Object>();
private Map<EventType,EventListenerGroupImpl> registeredEventListenersMap = prepareListenerMap();
@SuppressWarnings({ "unchecked" })
public <T> EventListenerGroupImpl<T> getEventListenerGroup(EventType<T> eventType) {
EventListenerGroupImpl<T> listeners = registeredEventListenersMap.get( eventType );
if ( listeners == null ) {
throw new HibernateException( "Unable to find listeners for type [" + eventType.eventName() + "]" );
}
return listeners;
}
@Override
public void addDuplicationStrategy(DuplicationStrategy strategy) {
for ( EventListenerGroupImpl group : registeredEventListenersMap.values() ) {
group.addDuplicationStrategy( strategy );
}
}
@Override
public <T> void setListeners(EventType<T> type, Class<T>... listenerClasses) {
setListeners( type, resolveListenerInstances( type, listenerClasses ) );
}
@SuppressWarnings( {"unchecked"})
private <T> T[] resolveListenerInstances(EventType<T> type, Class<T>... listenerClasses) {
T[] listeners = (T[]) Array.newInstance( type.baseListenerInterface(), listenerClasses.length );
for ( int i = 0; i < listenerClasses.length; i++ ) {
listeners[i] = resolveListenerInstance( listenerClasses[i] );
}
return listeners;
}
@SuppressWarnings( {"unchecked"})
private <T> T resolveListenerInstance(Class<T> listenerClass) {
T listenerInstance = (T) listenerClassToInstanceMap.get( listenerClass );
if ( listenerInstance == null ) {
listenerInstance = instantiateListener( listenerClass );
listenerClassToInstanceMap.put( listenerClass, listenerInstance );
}
return listenerInstance;
}
private <T> T instantiateListener(Class<T> listenerClass) {
try {
return listenerClass.newInstance();
}
catch ( Exception e ) {
throw new EventListenerRegistrationException(
"Unable to instantiate specified event listener class: " + listenerClass.getName(),
e
);
}
}
@Override
public <T> void setListeners(EventType<T> type, T... listeners) {
EventListenerGroupImpl<T> registeredListeners = getEventListenerGroup( type );
registeredListeners.clear();
if ( listeners != null ) {
for ( int i = 0, max = listeners.length; i < max; i++ ) {
registeredListeners.appendListener( listeners[i] );
}
}
}
@Override
public <T> void appendListeners(EventType<T> type, Class<T>... listenerClasses) {
appendListeners( type, resolveListenerInstances( type, listenerClasses ) );
}
@Override
public <T> void appendListeners(EventType<T> type, T... listeners) {
getEventListenerGroup( type ).appendListeners( listeners );
}
@Override
public <T> void prependListeners(EventType<T> type, Class<T>... listenerClasses) {
prependListeners( type, resolveListenerInstances( type, listenerClasses ) );
}
@Override
public <T> void prependListeners(EventType<T> type, T... listeners) {
getEventListenerGroup( type ).prependListeners( listeners );
}
private static Map<EventType,EventListenerGroupImpl> prepareListenerMap() {
final Map<EventType,EventListenerGroupImpl> workMap = new HashMap<EventType, EventListenerGroupImpl>();
// auto-flush listeners
prepareListeners(
AUTO_FLUSH,
new DefaultAutoFlushEventListener(),
workMap
);
// create listeners
prepareListeners(
PERSIST,
new DefaultPersistEventListener(),
workMap
);
// create-onflush listeners
prepareListeners(
PERSIST_ONFLUSH,
new DefaultPersistOnFlushEventListener(),
workMap
);
// delete listeners
prepareListeners(
DELETE,
new DefaultDeleteEventListener(),
workMap
);
// dirty-check listeners
prepareListeners(
DIRTY_CHECK,
new DefaultDirtyCheckEventListener(),
workMap
);
// evict listeners
prepareListeners(
EVICT,
new DefaultEvictEventListener(),
workMap
);
// flush listeners
prepareListeners(
FLUSH,
new DefaultFlushEventListener(),
workMap
);
// flush-entity listeners
prepareListeners(
FLUSH_ENTITY,
new DefaultFlushEntityEventListener(),
workMap
);
// load listeners
prepareListeners(
LOAD,
new DefaultLoadEventListener(),
workMap
);
// load-collection listeners
prepareListeners(
INIT_COLLECTION,
new DefaultInitializeCollectionEventListener(),
workMap
);
// lock listeners
prepareListeners(
LOCK,
new DefaultLockEventListener(),
workMap
);
// merge listeners
prepareListeners(
MERGE,
new DefaultMergeEventListener(),
workMap
);
// pre-collection-recreate listeners
prepareListeners(
PRE_COLLECTION_RECREATE,
workMap
);
// pre-collection-remove listeners
prepareListeners(
PRE_COLLECTION_REMOVE,
workMap
);
// pre-collection-update listeners
prepareListeners(
PRE_COLLECTION_UPDATE,
workMap
);
// pre-delete listeners
prepareListeners(
PRE_DELETE,
workMap
);
// pre-insert listeners
prepareListeners(
PRE_INSERT,
workMap
);
// pre-load listeners
prepareListeners(
PRE_LOAD,
new DefaultPreLoadEventListener(),
workMap
);
// pre-update listeners
prepareListeners(
PRE_UPDATE,
workMap
);
// post-collection-recreate listeners
prepareListeners(
POST_COLLECTION_RECREATE,
workMap
);
// post-collection-remove listeners
prepareListeners(
POST_COLLECTION_REMOVE,
workMap
);
// post-collection-update listeners
prepareListeners(
POST_COLLECTION_UPDATE,
workMap
);
// post-commit-delete listeners
prepareListeners(
POST_COMMIT_DELETE,
workMap
);
// post-commit-insert listeners
prepareListeners(
POST_COMMIT_INSERT,
workMap
);
// post-commit-update listeners
prepareListeners(
POST_COMMIT_UPDATE,
workMap
);
// post-delete listeners
prepareListeners(
POST_DELETE,
workMap
);
// post-insert listeners
prepareListeners(
POST_INSERT,
workMap
);
// post-load listeners
prepareListeners(
POST_LOAD,
new DefaultPostLoadEventListener(),
workMap
);
// post-update listeners
prepareListeners(
POST_UPDATE,
workMap
);
// update listeners
prepareListeners(
UPDATE,
new DefaultUpdateEventListener(),
workMap
);
// refresh listeners
prepareListeners(
REFRESH,
new DefaultRefreshEventListener(),
workMap
);
// replicate listeners
prepareListeners(
REPLICATE,
new DefaultReplicateEventListener(),
workMap
);
// save listeners
prepareListeners(
SAVE,
new DefaultSaveEventListener(),
workMap
);
// save-update listeners
prepareListeners(
SAVE_UPDATE,
new DefaultSaveOrUpdateEventListener(),
workMap
);
return Collections.unmodifiableMap( workMap );
}
private static <T> void prepareListeners(EventType<T> type, Map<EventType,EventListenerGroupImpl> map) {
prepareListeners( type, null, map );
}
private static <T> void prepareListeners(EventType<T> type, T defaultListener, Map<EventType,EventListenerGroupImpl> map) {
final EventListenerGroupImpl<T> listeners = new EventListenerGroupImpl<T>( type );
if ( defaultListener != null ) {
listeners.appendListener( defaultListener );
}
map.put( type, listeners );
}
}

View File

@ -0,0 +1,49 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.service.event.internal;
import org.hibernate.service.event.spi.EventListenerRegistry;
import org.hibernate.service.spi.ServiceInitiator;
import org.hibernate.service.spi.ServiceRegistry;
import java.util.Map;
/**
* Service initiator for {@link EventListenerRegistry}
*
* @author Steve Ebersole
*/
public class EventListenerServiceInitiator implements ServiceInitiator<EventListenerRegistry> {
public static final EventListenerServiceInitiator INSTANCE = new EventListenerServiceInitiator();
@Override
public Class<EventListenerRegistry> getServiceInitiated() {
return EventListenerRegistry.class;
}
@Override
public EventListenerRegistry initiateService(Map configurationValues, ServiceRegistry registry) {
return new EventListenerRegistryImpl();
}
}

View File

@ -0,0 +1,47 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.service.event.internal;
import org.hibernate.event.EventType;
import org.hibernate.service.event.spi.EventListenerRegistry;
/**
* Helper for handling various aspects of event listeners. Temporary because generally speaking this is legacy stuff
* that should change as we move forward
*
* @author Steve Ebersole
*/
public class TemporaryListenerHelper {
public static interface ListenerProcessor {
public void processListener(Object listener);
}
public static void processListeners(EventListenerRegistry registryRegistry, ListenerProcessor processer) {
for ( EventType eventType : EventType.values() ) {
for ( Object listener : registryRegistry.getEventListenerGroup( eventType ).listeners() ) {
processer.processListener( listener );
}
}
}
}

View File

@ -0,0 +1,58 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.service.event.spi;
/**
* Defines listener duplication checking strategy, both in terms of when a duplication is detected (see
* {@link #areMatch}) as well as how to handle a duplication (see {@link #getAction}).
*
* @author Steve Ebersole
*/
public interface DuplicationStrategy {
/**
* The enumerated list of actions available on duplication match
*/
public static enum Action {
ERROR,
KEEP_ORIGINAL,
REPLACE_ORIGINAL
}
/**
* Are the two listener instances considered a duplication?
*
* @param listener The listener we are currently trying to register
* @param original An already registered listener
*
* @return {@literal true} if the two instances are considered a duplication; {@literal false} otherwise
*/
public boolean areMatch(Object listener, Object original);
/**
* How should a duplication be handled?
*
* @return The strategy for handling duplication
*/
public Action getAction();
}

View File

@ -0,0 +1,74 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.service.event.spi;
import java.io.Serializable;
import org.hibernate.event.EventType;
/**
* Contract for a groups of events listeners for a particular event type.
*
* @author Steve Ebersole
*/
public interface EventListenerGroup<T> extends Serializable {
/**
* Retrieve the event type associated with this groups of listeners.
*
* @return The event type.
*/
public EventType<T> getEventType();
/**
* Are there no listeners registered?
*
* @return {@literal true} if no listeners are registered; {@literal false} otherwise.
*/
public boolean isEmpty();
public int count();
public Iterable<T> listeners();
/**
* Mechanism to more finely control the notion of duplicates.
* <p/>
* For example, say you are registering listeners for an extension library. This extension library
* could define a "marker interface" which indicates listeners related to it and register a strategy
* that checks against that marker interface.
*
* @param strategy The duplication strategy
*/
public void addDuplicationStrategy(DuplicationStrategy strategy);
public void appendListener(T listener);
public void appendListeners(T... listeners);
public void prependListener(T listener);
public void prependListeners(T... listeners);
public void clear();
}

View File

@ -0,0 +1,41 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.service.event.spi;
import org.hibernate.HibernateException;
/**
* Indicates a problem registering an event listener.
*
* @author Steve Ebersole
*/
public class EventListenerRegistrationException extends HibernateException {
public EventListenerRegistrationException(String s) {
super( s );
}
public EventListenerRegistrationException(String string, Throwable root) {
super( string, root );
}
}

View File

@ -0,0 +1,51 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.service.event.spi;
import java.io.Serializable;
import org.hibernate.event.EventType;
import org.hibernate.service.spi.Service;
/**
* Service for accessing each {@link EventListenerGroup} by {@link EventType}, as well as convenience
* methods for managing the listeners registered in each {@link EventListenerGroup}.
*
* @author Steve Ebersole
*/
public interface EventListenerRegistry extends Service, Serializable {
// todo : rename this to getEventListenerGroup
public <T> EventListenerGroup<T> getEventListenerGroup(EventType<T> eventType);
public void addDuplicationStrategy(DuplicationStrategy strategy);
public <T> void setListeners(EventType<T> type, Class<T>... listeners);
public <T> void setListeners(EventType<T> type, T... listeners);
public <T> void appendListeners(EventType<T> type, Class<T>... listeners);
public <T> void appendListeners(EventType<T> type, T... listeners);
public <T> void prependListeners(EventType<T> type, Class<T>... listeners);
public <T> void prependListeners(EventType<T> type, T... listeners);
}

View File

@ -40,7 +40,9 @@ import org.hibernate.engine.EntityKey;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.event.EventSource;
import org.hibernate.event.EventType;
import org.hibernate.event.PersistEvent;
import org.hibernate.event.PersistEventListener;
import org.hibernate.id.Assigned;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.PersistentClass;
@ -49,6 +51,7 @@ import org.hibernate.property.Getter;
import org.hibernate.property.Setter;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.ProxyFactory;
import org.hibernate.service.event.spi.EventListenerRegistry;
import org.hibernate.tuple.Instantiator;
import org.hibernate.tuple.StandardProperty;
import org.hibernate.tuple.VersionProperty;
@ -66,8 +69,10 @@ import org.hibernate.type.Type;
*/
public abstract class AbstractEntityTuplizer implements EntityTuplizer {
private static final HibernateLogger LOG = Logger.getMessageLogger(HibernateLogger.class,
AbstractEntityTuplizer.class.getName());
private static final HibernateLogger LOG = Logger.getMessageLogger(
HibernateLogger.class,
AbstractEntityTuplizer.class.getName()
);
//TODO: currently keeps Getters and Setters (instead of PropertyAccessors) because of the way getGetter() and getSetter() are implemented currently; yuck!
@ -372,9 +377,8 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
else {
LOG.debugf( "Performing implicit derived identity cascade" );
final PersistEvent event = new PersistEvent( null, propertyValues[i], (EventSource) session );
for ( int x = 0; x < session.getListeners().getPersistEventListeners().length; x++ ) {
session.getListeners().getPersistEventListeners()[x].onPersist( event );
for ( PersistEventListener listener : persistEventListeners( session ) ) {
listener.onPersist( event );
}
pcEntry = session.getPersistenceContext().getEntry( propertyValues[i] );
if ( pcEntry == null || pcEntry.getId() == null ) {
@ -425,6 +429,15 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
}
}
private static Iterable<PersistEventListener> persistEventListeners(SessionImplementor session) {
return session
.getFactory()
.getServiceRegistry()
.getService( EventListenerRegistry.class )
.getEventListenerGroup( EventType.PERSIST )
.listeners();
}
/**
* {@inheritDoc}
*/

View File

@ -1,11 +1,10 @@
//$Id$
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* Copyright (c) 2008-2011, 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 Middleware LLC.
* 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
@ -24,45 +23,33 @@
*/
package org.hibernate.test.annotations.access.xml;
import javax.persistence.AccessType;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.persistence.AccessType;
import junit.framework.TestCase;
import org.hibernate.EntityMode;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Environment;
import org.hibernate.cfg.Configuration;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.property.BasicPropertyAccessor;
import org.hibernate.property.DirectPropertyAccessor;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.testing.ServiceRegistryBuilder;
import org.hibernate.tuple.entity.EntityMetamodel;
import org.hibernate.tuple.entity.PojoEntityTuplizer;
import org.junit.Assert;
import org.junit.Test;
import org.hibernate.testing.junit4.BaseUnitTestCase;
/**
* Test verifying that it is possible to configure the access type via xml configuration.
*
* @author Hardy Ferentschik
*/
public class XmlAccessTest extends TestCase {
private ServiceRegistry serviceRegistry;
@Override
protected void setUp() {
serviceRegistry = ServiceRegistryBuilder.buildServiceRegistry( Environment.getProperties() );
}
@Override
protected void tearDown() {
if ( serviceRegistry != null ) {
ServiceRegistryBuilder.destroy( serviceRegistry );
}
}
public class XmlAccessTest extends BaseUnitTestCase {
@Test
public void testAccessOnBasicXmlElement() throws Exception {
Class<?> classUnderTest = Tourist.class;
List<Class<?>> classes = new ArrayList<Class<?>>();
@ -80,6 +67,7 @@ public class XmlAccessTest extends TestCase {
assertAccessType( factory, classUnderTest, AccessType.PROPERTY );
}
@Test
public void testAccessOnPersistenceUnitDefaultsXmlElement() throws Exception {
Class<?> classUnderTest = Tourist.class;
List<Class<?>> classes = new ArrayList<Class<?>>();
@ -97,6 +85,7 @@ public class XmlAccessTest extends TestCase {
assertAccessType( factory, classUnderTest, AccessType.PROPERTY );
}
@Test
public void testAccessOnEntityMappingsXmlElement() throws Exception {
Class<?> classUnderTest = Tourist.class;
List<Class<?>> classes = new ArrayList<Class<?>>();
@ -114,6 +103,7 @@ public class XmlAccessTest extends TestCase {
assertAccessType( factory, classUnderTest, AccessType.PROPERTY );
}
@Test
public void testAccessOnEntityXmlElement() throws Exception {
Class<?> classUnderTest = Tourist.class;
List<Class<?>> classes = new ArrayList<Class<?>>();
@ -131,6 +121,7 @@ public class XmlAccessTest extends TestCase {
assertAccessType( factory, classUnderTest, AccessType.PROPERTY );
}
@Test
public void testAccessOnMappedSuperClassXmlElement() throws Exception {
Class<?> classUnderTest = Waiter.class;
List<Class<?>> classes = new ArrayList<Class<?>>();
@ -142,6 +133,7 @@ public class XmlAccessTest extends TestCase {
assertAccessType( factory, classUnderTest, AccessType.FIELD );
}
@Test
public void testAccessOnAssociationXmlElement() throws Exception {
Class<?> classUnderTest = RentalCar.class;
List<Class<?>> classes = new ArrayList<Class<?>>();
@ -153,6 +145,7 @@ public class XmlAccessTest extends TestCase {
assertAccessType( factory, classUnderTest, AccessType.PROPERTY );
}
@Test
public void testAccessOnEmbeddedXmlElement() throws Exception {
Class<?> classUnderTest = Cook.class;
List<Class<?>> classes = new ArrayList<Class<?>>();
@ -164,6 +157,7 @@ public class XmlAccessTest extends TestCase {
assertAccessType( factory, classUnderTest, AccessType.PROPERTY );
}
@Test
public void testAccessOnElementCollectionXmlElement() throws Exception {
Class<?> classUnderTest = Boy.class;
List<Class<?>> classes = new ArrayList<Class<?>>();
@ -177,7 +171,7 @@ public class XmlAccessTest extends TestCase {
private SessionFactoryImplementor buildSessionFactory(List<Class<?>> classesUnderTest, List<String> configFiles) {
assert classesUnderTest != null;
assert configFiles != null;
AnnotationConfiguration cfg = new AnnotationConfiguration();
Configuration cfg = new Configuration();
for ( Class<?> clazz : classesUnderTest ) {
cfg.addAnnotatedClass( clazz );
}
@ -185,7 +179,7 @@ public class XmlAccessTest extends TestCase {
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream( configFile );
cfg.addInputStream( is );
}
return ( SessionFactoryImplementor ) cfg.buildSessionFactory( serviceRegistry );
return ( SessionFactoryImplementor ) cfg.buildSessionFactory();
}
// uses the first getter of the tupelizer for the assertions
@ -195,13 +189,13 @@ public class XmlAccessTest extends TestCase {
.getEntityMetamodel();
PojoEntityTuplizer tuplizer = ( PojoEntityTuplizer ) metaModel.getTuplizer( EntityMode.POJO );
if ( AccessType.FIELD.equals( accessType ) ) {
assertTrue(
Assert.assertTrue(
"Field access was expected.",
tuplizer.getGetter( 0 ) instanceof DirectPropertyAccessor.DirectGetter
);
}
else {
assertTrue(
Assert.assertTrue(
"Property access was expected.",
tuplizer.getGetter( 0 ) instanceof BasicPropertyAccessor.BasicGetter
);

View File

@ -1,353 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, 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.cfg;
import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.cfg.Configuration;
import org.hibernate.event.DeleteEvent;
import org.hibernate.event.DeleteEventListener;
import org.hibernate.event.def.DefaultDeleteEventListener;
import org.junit.Test;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* @author Gail Badner
*/
public class ListenerTest extends BaseUnitTestCase {
public static class InvalidListenerForTest {
}
public static class DeleteListenerForTest implements DeleteEventListener {
public void onDelete(DeleteEvent event) throws HibernateException {
}
public void onDelete(DeleteEvent event, Set transientEntities) throws HibernateException {
}
}
public static class AnotherDeleteListenerForTest implements DeleteEventListener {
public void onDelete(DeleteEvent event) throws HibernateException {
}
public void onDelete(DeleteEvent event, Set transientEntities) throws HibernateException {
}
}
@Test
public void testSetListenerNullClass() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
cfg.setListener( "delete", null );
assertEquals( 0, cfg.getEventListeners().getDeleteEventListeners().length );
}
@Test
public void testSetListenersNullClass() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
cfg.setListeners( "delete", null );
assertEquals( 0, cfg.getEventListeners().getDeleteEventListeners().length );
}
@Test
public void testSetListenerEmptyClassNameArray() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
try {
cfg.setListener( "delete", new String[] { } );
fail( "should have thrown java.lang.ArrayStoreException" );
}
catch ( ArrayStoreException ex ) {
// expected
}
}
@Test
public void testSetListenersEmptyClassNsmeArray() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
cfg.setListeners( "delete", new String[] { } );
assertEquals( 0, cfg.getEventListeners().getDeleteEventListeners().length );
}
@Test
public void testSetListenerEmptyClassObjectArray() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
try {
cfg.setListener( "delete", new Object[] { } );
fail( "should have thrown java.lang.ArrayStoreException" );
}
catch ( ArrayStoreException ex ) {
// expected
}
}
@Test
public void testSetListenersEmptyClassObjectArray() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
try {
cfg.setListeners( "delete", new Object[] { } );
fail( "should have thrown ClassCastException" );
}
catch ( ClassCastException ex ) {
// expected
}
}
@Test
public void testSetListenerEmptyClassArray() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
try {
cfg.setListener( "delete", new DefaultDeleteEventListener[] { } );
fail( "should have thrown java.lang.ArrayStoreException" );
}
catch ( ArrayStoreException ex ) {
// expected
}
}
@Test
public void testSetListenersEmptyClassArray() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
cfg.setListeners( "delete", new DefaultDeleteEventListener[] { } );
assertEquals( 0, cfg.getEventListeners().getDeleteEventListeners().length );
}
@Test
public void testSetListenerUnknownClassName() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
try {
cfg.setListener( "delete", "UnknownClassName" );
fail( "should have thrown MappingException" );
}
catch ( MappingException ex ) {
// expected
}
}
@Test
public void testSetListenersUnknownClassName() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
try {
cfg.setListeners( "delete", new String[] { "UnknownClassName" } );
fail( "should have thrown MappingException" );
}
catch ( MappingException ex ) {
// expected
}
}
@Test
public void testSetListenerInvalidClassName() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
try {
cfg.setListener( "delete", InvalidListenerForTest.class.getName() );
fail( "should have thrown MappingException" );
}
catch ( MappingException ex ) {
// expected
}
}
@Test
public void testSetListenersInvalidClassName() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
try {
cfg.setListeners( "delete", new String[] { InvalidListenerForTest.class.getName() } );
fail( "should have thrown MappingException" );
}
catch ( MappingException ex ) {
// expected
}
}
@Test
public void testSetListenerClassName() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
cfg.setListener( "delete", DeleteListenerForTest.class.getName() );
assertEquals( 1, cfg.getEventListeners().getDeleteEventListeners().length );
assertTrue( cfg.getEventListeners().getDeleteEventListeners()[0] instanceof DeleteListenerForTest );
}
@Test
public void testSetListenersClassName() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
cfg.setListeners( "delete", new String[] { DeleteListenerForTest.class.getName() } );
assertEquals( 1, cfg.getEventListeners().getDeleteEventListeners().length );
assertTrue( cfg.getEventListeners().getDeleteEventListeners()[0] instanceof DeleteListenerForTest );
}
@Test
public void testSetListenerClassNames() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
try {
cfg.setListener(
"delete", new String[] {
DeleteListenerForTest.class.getName(),
AnotherDeleteListenerForTest.class.getName()
}
);
fail( "should have thrown java.lang.ArrayStoreException" );
}
catch ( ArrayStoreException ex ) {
// expected
}
}
@Test
public void testSetListenersClassNames() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
cfg.setListeners(
"delete", new String[] {
DeleteListenerForTest.class.getName(),
AnotherDeleteListenerForTest.class.getName()
}
);
assertEquals( 2, cfg.getEventListeners().getDeleteEventListeners().length );
assertTrue( cfg.getEventListeners().getDeleteEventListeners()[0] instanceof DeleteListenerForTest );
assertTrue( cfg.getEventListeners().getDeleteEventListeners()[1] instanceof AnotherDeleteListenerForTest );
}
@Test
public void testSetListenerClassInstance() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
cfg.setListener( "delete", new DeleteListenerForTest() );
assertEquals( 1, cfg.getEventListeners().getDeleteEventListeners().length );
}
@Test
public void testSetListenersClassInstances() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
cfg.setListeners(
"delete", new DeleteEventListener[] {
new DeleteListenerForTest(),
new AnotherDeleteListenerForTest()
}
);
assertEquals( 2, cfg.getEventListeners().getDeleteEventListeners().length );
assertTrue( cfg.getEventListeners().getDeleteEventListeners()[0] instanceof DeleteListenerForTest );
assertTrue( cfg.getEventListeners().getDeleteEventListeners()[1] instanceof AnotherDeleteListenerForTest );
}
@Test
public void testSetListenerInvalidClassInstance() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
try {
cfg.setListener( "delete", new InvalidListenerForTest() );
fail( "should have thrown java.lang.ArrayStoreException" );
}
catch ( ArrayStoreException ex ) {
// expected
}
}
@Test
public void testSetListenersInvalidClassInstances() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
try {
cfg.setListeners( "delete", new InvalidListenerForTest[] { new InvalidListenerForTest() } );
fail( "should have thrown java.lang.ClassCastException" );
}
catch ( ClassCastException ex ) {
// expected
}
}
@Test
public void testSetListenerNullType() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
try {
cfg.setListener( null, new DeleteListenerForTest() );
fail( "should have thrown MappingException" );
}
catch ( MappingException ex ) {
// expected
}
}
@Test
public void testSetListenersNullType() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
try {
cfg.setListeners( null, new DeleteEventListener[] { new DeleteListenerForTest() } );
fail( "should have thrown MappingException" );
}
catch ( MappingException ex ) {
// expected
}
}
@Test
public void testSetListenerUnknownType() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
try {
cfg.setListener( "unknown-type", new DeleteListenerForTest() );
fail( "should have thrown MappingException" );
}
catch ( MappingException ex ) {
// expected
}
}
@Test
public void testSetListenersUnknownType() {
Configuration cfg = new Configuration();
assertNotNull( cfg.getEventListeners().getDeleteEventListeners() );
try {
cfg.setListeners( "unknown-type", new DeleteEventListener[] { new DeleteListenerForTest() } );
fail( "should have thrown MappingException" );
}
catch ( MappingException ex ) {
// expected
}
}
}

View File

@ -46,7 +46,9 @@ public class PersisterClassProviderTest extends BaseUnitTestCase {
//no exception as the GoofyPersisterClassProvider is not set
SessionFactory sessionFactory = cfg.buildSessionFactory( serviceRegistry );
sessionFactory.close();
ServiceRegistryBuilder.destroy( serviceRegistry );
serviceRegistry = ServiceRegistryBuilder.buildServiceRegistry( cfg.getProperties() );
serviceRegistry.registerService( PersisterClassResolver.class, new GoofyPersisterClassProvider() );
cfg = new Configuration();
cfg.addAnnotatedClass( Gate.class );
@ -61,10 +63,15 @@ public class PersisterClassProviderTest extends BaseUnitTestCase {
( (GoofyException) e.getCause() ).getValue()
);
}
finally {
ServiceRegistryBuilder.destroy( serviceRegistry );
}
cfg = new Configuration();
cfg.addAnnotatedClass( Portal.class );
cfg.addAnnotatedClass( Window.class );
serviceRegistry = ServiceRegistryBuilder.buildServiceRegistry( cfg.getProperties() );
serviceRegistry.registerService( PersisterClassResolver.class, new GoofyPersisterClassProvider() );
try {
sessionFactory = cfg.buildSessionFactory( serviceRegistry );
sessionFactory.close();
@ -75,8 +82,7 @@ public class PersisterClassProviderTest extends BaseUnitTestCase {
GoofyPersisterClassProvider.NoopCollectionPersister.class,
( (GoofyException) e.getCause() ).getValue() );
}
if ( serviceRegistry != null ) {
finally {
ServiceRegistryBuilder.destroy( serviceRegistry );
}
}

View File

@ -1,32 +1,37 @@
//$Id: $
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution statements
* applied by the authors.
* Copyright (c) 2007-2011, 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.
*
* All third-party contributions are distributed under license by Red Hat
* Middleware LLC. 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.
* 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.
*
* 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
* 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.event.collection;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.SessionFactory;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.event.AbstractCollectionEvent;
import org.hibernate.event.EventType;
import org.hibernate.event.InitializeCollectionEvent;
import org.hibernate.event.InitializeCollectionEventListener;
import org.hibernate.event.PostCollectionRecreateEvent;
import org.hibernate.event.PostCollectionRecreateEventListener;
import org.hibernate.event.PostCollectionRemoveEvent;
@ -40,14 +45,14 @@ import org.hibernate.event.PreCollectionRemoveEventListener;
import org.hibernate.event.PreCollectionUpdateEvent;
import org.hibernate.event.PreCollectionUpdateEventListener;
import org.hibernate.event.def.DefaultInitializeCollectionEventListener;
import org.hibernate.impl.SessionFactoryImpl;
import org.hibernate.service.event.spi.EventListenerRegistry;
/**
* Author: Gail Badner
* @author Gail Badner
* @author Steve Ebersole
*/
public class CollectionListeners {
public interface Listener extends Serializable {
void addEvent(AbstractCollectionEvent event, Listener listener);
}
@ -160,28 +165,18 @@ public class CollectionListeners {
postCollectionRecreateListener = new PostCollectionRecreateListener( this );
postCollectionRemoveListener = new PostCollectionRemoveListener( this );
postCollectionUpdateListener = new PostCollectionUpdateListener( this );
SessionFactoryImpl impl = ( SessionFactoryImpl ) sf;
impl.getEventListeners().setInitializeCollectionEventListeners(
new InitializeCollectionEventListener[] { initializeCollectionListener }
);
impl.getEventListeners().setPreCollectionRecreateEventListeners(
new PreCollectionRecreateEventListener[] { preCollectionRecreateListener }
);
impl.getEventListeners().setPostCollectionRecreateEventListeners(
new PostCollectionRecreateEventListener[] { postCollectionRecreateListener }
);
impl.getEventListeners().setPreCollectionRemoveEventListeners(
new PreCollectionRemoveEventListener[] { preCollectionRemoveListener }
);
impl.getEventListeners().setPostCollectionRemoveEventListeners(
new PostCollectionRemoveEventListener[] { postCollectionRemoveListener }
);
impl.getEventListeners().setPreCollectionUpdateEventListeners(
new PreCollectionUpdateEventListener[] { preCollectionUpdateListener }
);
impl.getEventListeners().setPostCollectionUpdateEventListeners(
new PostCollectionUpdateEventListener[] { postCollectionUpdateListener }
);
EventListenerRegistry registry = ( (SessionFactoryImplementor) sf ).getServiceRegistry().getService( EventListenerRegistry.class );
registry.setListeners( EventType.INIT_COLLECTION, initializeCollectionListener );
registry.setListeners( EventType.PRE_COLLECTION_RECREATE, preCollectionRecreateListener );
registry.setListeners( EventType.POST_COLLECTION_RECREATE, postCollectionRecreateListener );
registry.setListeners( EventType.PRE_COLLECTION_REMOVE, preCollectionRemoveListener );
registry.setListeners( EventType.POST_COLLECTION_REMOVE, postCollectionRemoveListener );
registry.setListeners( EventType.PRE_COLLECTION_UPDATE, preCollectionUpdateListener );
registry.setListeners( EventType.POST_COLLECTION_UPDATE, postCollectionUpdateListener );
}
public void addEvent(AbstractCollectionEvent event, Listener listener) {

View File

@ -31,10 +31,14 @@ import org.hibernate.cfg.Configuration;
import org.hibernate.event.DeleteEvent;
import org.hibernate.event.DeleteEventListener;
import org.hibernate.event.Destructible;
import org.hibernate.event.EventType;
import org.hibernate.event.Initializable;
import org.hibernate.service.event.spi.EventListenerRegistry;
import org.hibernate.service.internal.ServiceRegistryImpl;
import org.junit.Test;
import org.hibernate.testing.FailureExpected;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.junit.Assert.assertEquals;
@ -55,10 +59,16 @@ public class CallbackTest extends BaseCoreFunctionalTestCase {
public void configure(Configuration cfg) {
cfg.setSessionFactoryObserver( observer );
cfg.getEventListeners().setDeleteEventListeners( new DeleteEventListener[] { listener } );
}
@Override
protected void applyServices(ServiceRegistryImpl serviceRegistry) {
super.applyServices( serviceRegistry );
serviceRegistry.getService( EventListenerRegistry.class ).setListeners( EventType.DELETE, listener );
}
@Test
@FailureExpected( jiraKey = "HHH-5913", message = "Need to figure out how to initialize/destroy event listeners now")
public void testCallbacks() {
assertEquals( "observer not notified of creation", 1, observer.creationCount );
assertEquals( "listener not notified of creation", 1, listener.initCount );

View File

@ -30,6 +30,7 @@ import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.CascadingAction;
import org.hibernate.event.AutoFlushEventListener;
import org.hibernate.event.EventType;
import org.hibernate.event.FlushEntityEventListener;
import org.hibernate.event.FlushEventListener;
import org.hibernate.event.PersistEventListener;
@ -39,6 +40,8 @@ import org.hibernate.event.def.DefaultFlushEventListener;
import org.hibernate.event.def.DefaultPersistEventListener;
import org.hibernate.internal.util.collections.IdentityMap;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.service.event.spi.EventListenerRegistry;
import org.hibernate.service.internal.ServiceRegistryImpl;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
@ -59,11 +62,18 @@ public abstract class AbstractJPATest extends BaseCoreFunctionalTestCase {
cfg.setProperty( Environment.JPAQL_STRICT_COMPLIANCE, "true" );
cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "false" );
cfg.setEntityNotFoundDelegate( new JPAEntityNotFoundDelegate() );
cfg.getEventListeners().setPersistEventListeners( buildPersistEventListeners() );
cfg.getEventListeners().setPersistOnFlushEventListeners( buildPersisOnFlushEventListeners() );
cfg.getEventListeners().setAutoFlushEventListeners( buildAutoFlushEventListeners() );
cfg.getEventListeners().setFlushEventListeners( buildFlushEventListeners() );
cfg.getEventListeners().setFlushEntityEventListeners( buildFlushEntityEventListeners() );
}
@Override
protected void applyServices(ServiceRegistryImpl serviceRegistry) {
super.applyServices( serviceRegistry );
EventListenerRegistry eventListenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );
eventListenerRegistry.setListeners( EventType.PERSIST, buildPersistEventListeners() );
eventListenerRegistry.setListeners( EventType.PERSIST_ONFLUSH, buildPersisOnFlushEventListeners() );
eventListenerRegistry.setListeners( EventType.AUTO_FLUSH, buildAutoFlushEventListeners() );
eventListenerRegistry.setListeners( EventType.FLUSH, buildFlushEventListeners() );
eventListenerRegistry.setListeners( EventType.FLUSH_ENTITY, buildFlushEntityEventListeners() );
}
@Override

View File

@ -27,9 +27,12 @@ import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.event.EventType;
import org.hibernate.event.LoadEvent;
import org.hibernate.event.LoadEventListener;
import org.hibernate.event.def.DefaultLoadEventListener;
import org.hibernate.service.event.spi.EventListenerRegistry;
import org.hibernate.service.internal.ServiceRegistryImpl;
import org.junit.Test;
@ -51,12 +54,14 @@ public class EagerKeyManyToOneTest extends BaseCoreFunctionalTestCase {
public void configure(Configuration cfg) {
super.configure( cfg );
cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
LoadEventListener[] baseListeners = cfg.getEventListeners().getLoadEventListeners();
int baseLength = baseListeners.length;
LoadEventListener[] expandedListeners = new LoadEventListener[ baseLength + 1 ];
expandedListeners[ 0 ] = new CustomLoadListener();
System.arraycopy( baseListeners, 0, expandedListeners, 1, baseLength );
cfg.getEventListeners().setLoadEventListeners( expandedListeners );
}
@Override
protected void applyServices(ServiceRegistryImpl serviceRegistry) {
super.applyServices( serviceRegistry );
EventListenerRegistry eventListenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );
eventListenerRegistry.prependListeners( EventType.LOAD, new CustomLoadListener() );
}
@Test

View File

@ -101,10 +101,11 @@ public class StatsTest extends BaseCoreFunctionalTestCase {
tx.commit();
s.close();
// open second SessionFactory
Collection coll = configuration().getCollectionMapping(Continent.class.getName() + ".countries");
coll.setFetchMode(FetchMode.JOIN);
coll.setLazy(false);
SessionFactory sf = configuration().buildSessionFactory( serviceRegistry() );
SessionFactory sf = configuration().buildSessionFactory();
stats = sf.getStatistics();
stats.clear();
stats.setStatisticsEnabled(true);
@ -123,10 +124,11 @@ public class StatsTest extends BaseCoreFunctionalTestCase {
s.close();
sf.close();
// open third SessionFactory
coll = configuration().getCollectionMapping(Continent.class.getName() + ".countries");
coll.setFetchMode(FetchMode.SELECT);
coll.setLazy(false);
sf = configuration().buildSessionFactory( serviceRegistry() );
sf = configuration().buildSessionFactory();
stats = sf.getStatistics();
stats.clear();
stats.setStatisticsEnabled(true);

View File

@ -68,13 +68,13 @@ import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.MappingException;
import org.hibernate.MappingNotFoundException;
import org.hibernate.SessionFactory;
import org.hibernate.SessionFactoryObserver;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.cfg.annotations.reflection.XMLContext;
import org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider;
import org.hibernate.ejb.event.JpaEventListenerRegistration;
import org.hibernate.ejb.instrument.InterceptFieldClassFileTransformer;
import org.hibernate.ejb.packaging.JarVisitorFactory;
import org.hibernate.ejb.packaging.NamedInputStream;
@ -88,7 +88,6 @@ import org.hibernate.ejb.util.NamingHelper;
import org.hibernate.engine.FilterDefinition;
import org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory;
import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory;
import org.hibernate.event.EventListeners;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
@ -107,7 +106,7 @@ import org.hibernate.service.jdbc.connections.internal.DatasourceConnectionProvi
* Allow a fine tuned configuration of an EJB 3.0 EntityManagerFactory
*
* A Ejb3Configuration object is only guaranteed to create one EntityManagerFactory.
* Multiple usage of #buildEntityManagerFactory() is not guaranteed.
* Multiple usage of {@link #buildEntityManagerFactory()} is not guaranteed.
*
* After #buildEntityManagerFactory() has been called, you no longer can change the configuration
* state (no class adding, no property change etc)
@ -122,8 +121,10 @@ import org.hibernate.service.jdbc.connections.internal.DatasourceConnectionProvi
*/
public class Ejb3Configuration implements Serializable, Referenceable {
private static final EntityManagerLogger LOG = Logger.getMessageLogger(EntityManagerLogger.class,
Ejb3Configuration.class.getName());
private static final EntityManagerLogger LOG = Logger.getMessageLogger(
EntityManagerLogger.class,
Ejb3Configuration.class.getName()
);
private static final String IMPLEMENTATION_NAME = HibernatePersistence.class.getName();
private static final String META_INF_ORM_XML = "META-INF/orm.xml";
private static final String PARSED_MAPPING_DOMS = "hibernate.internal.mapping_doms";
@ -142,7 +143,6 @@ public class Ejb3Configuration implements Serializable, Referenceable {
private Configuration cfg;
//made transient and not restored in deserialization on purpose, should no longer be called after restoration
private transient EventListenerConfigurator listenerConfigurator;
private PersistenceUnitTransactionType transactionType;
private boolean discardOnClose;
//made transient and not restored in deserialization on purpose, should no longer be called after restoration
@ -153,7 +153,6 @@ public class Ejb3Configuration implements Serializable, Referenceable {
public Ejb3Configuration() {
cfg = new Configuration();
cfg.setEntityNotFoundDelegate( ejb3EntityNotFoundDelegate );
listenerConfigurator = new EventListenerConfigurator( this );
}
/**
@ -882,6 +881,8 @@ public class Ejb3Configuration implements Serializable, Referenceable {
try {
configure( (Properties)null, null );
NamingHelper.bind(this);
// todo : temporary -> HHH-5562
new JpaEventListenerRegistration().apply( serviceRegistry, cfg.createMappings(), cfg.getProperties() );
return new EntityManagerFactoryImpl(
transactionType,
discardOnClose,
@ -1061,10 +1062,6 @@ public class Ejb3Configuration implements Serializable, Referenceable {
addSecurity( jaccKeys, preparedProperties, workingVars );
}
//initialize listeners
listenerConfigurator.setProperties( preparedProperties );
listenerConfigurator.configure();
//some spec compliance checking
//TODO centralize that?
if (!"true".equalsIgnoreCase(cfg.getProperty(Environment.AUTOCOMMIT))) LOG.jdbcAutoCommitFalseBreaksEjb3Spec(Environment.AUTOCOMMIT);
@ -1342,25 +1339,6 @@ public class Ejb3Configuration implements Serializable, Referenceable {
}
}
/*
TODO: not needed any more?
public Settings buildSettings(ConnectionProvider connectionProvider) throws HibernateException {
Thread thread = null;
ClassLoader contextClassLoader = null;
if (overridenClassLoader != null) {
thread = Thread.currentThread();
contextClassLoader = thread.getContextClassLoader();
thread.setContextClassLoader( overridenClassLoader );
}
try {
return settingsFactory.buildSettings( cfg.getProperties(), connectionProvider );
}
finally {
if (thread != null) thread.setContextClassLoader( contextClassLoader );
}
}
*/
public Ejb3Configuration addProperties(Properties props) {
cfg.addProperties( props );
return this;
@ -1491,14 +1469,6 @@ public class Ejb3Configuration implements Serializable, Referenceable {
}
}
public EventListeners getEventListeners() {
return cfg.getEventListeners();
}
SessionFactory buildSessionFactory(ServiceRegistry serviceRegistry) throws HibernateException {
return cfg.buildSessionFactory( serviceRegistry );
}
public Iterator getTableMappings() {
return cfg.getTableMappings();
}
@ -1563,14 +1533,6 @@ public class Ejb3Configuration implements Serializable, Referenceable {
return this;
}
public void setListeners(String type, String[] listenerClasses) {
cfg.setListeners( type, listenerClasses );
}
public void setListeners(String type, Object[] listeners) {
cfg.setListeners( type, listeners );
}
/**
* This API is intended to give a read-only configuration.
* It is sueful when working with SchemaExport or any Configuration based

View File

@ -1,264 +0,0 @@
/*
* Copyright (c) 2009, Red Hat Middleware LLC 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 Middleware LLC.
*
* 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.ejb;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.ejb.event.CallbackHandlerConsumer;
import org.hibernate.ejb.event.EJB3AutoFlushEventListener;
import org.hibernate.ejb.event.EJB3DeleteEventListener;
import org.hibernate.ejb.event.EJB3FlushEntityEventListener;
import org.hibernate.ejb.event.EJB3FlushEventListener;
import org.hibernate.ejb.event.EJB3MergeEventListener;
import org.hibernate.ejb.event.EJB3PersistEventListener;
import org.hibernate.ejb.event.EJB3PersistOnFlushEventListener;
import org.hibernate.ejb.event.EJB3PostDeleteEventListener;
import org.hibernate.ejb.event.EJB3PostInsertEventListener;
import org.hibernate.ejb.event.EJB3PostLoadEventListener;
import org.hibernate.ejb.event.EJB3PostUpdateEventListener;
import org.hibernate.ejb.event.EJB3SaveEventListener;
import org.hibernate.ejb.event.EJB3SaveOrUpdateEventListener;
import org.hibernate.ejb.event.EntityCallbackHandler;
import org.hibernate.event.AutoFlushEventListener;
import org.hibernate.event.DeleteEventListener;
import org.hibernate.event.EventListeners;
import org.hibernate.event.FlushEntityEventListener;
import org.hibernate.event.FlushEventListener;
import org.hibernate.event.MergeEventListener;
import org.hibernate.event.PersistEventListener;
import org.hibernate.event.PostDeleteEventListener;
import org.hibernate.event.PostInsertEventListener;
import org.hibernate.event.PostLoadEventListener;
import org.hibernate.event.PostUpdateEventListener;
import org.hibernate.event.PreDeleteEventListener;
import org.hibernate.event.PreInsertEventListener;
import org.hibernate.event.PreLoadEventListener;
import org.hibernate.event.PreUpdateEventListener;
import org.hibernate.event.SaveOrUpdateEventListener;
import org.hibernate.event.def.DefaultPostLoadEventListener;
import org.hibernate.event.def.DefaultPreLoadEventListener;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.secure.JACCPreDeleteEventListener;
import org.hibernate.secure.JACCPreInsertEventListener;
import org.hibernate.secure.JACCPreLoadEventListener;
import org.hibernate.secure.JACCPreUpdateEventListener;
import org.hibernate.secure.JACCSecurityListener;
/**
* @author Emmanuel Bernard
*/
public class EventListenerConfigurator {
private static final Object[] READER_METHOD_ARGS = new Object[0];
private Ejb3Configuration configuration;
private boolean isSecurity;
public EventListenerConfigurator(Ejb3Configuration configuration) {
this.configuration = configuration;
EventListeners listenerConfig = configuration.getEventListeners();
//Action event
//EJB3-specific ops listeners
listenerConfig.setFlushEventListeners( new FlushEventListener[] { EJB3FlushEventListener.INSTANCE } );
//EJB3-specific ops listeners
listenerConfig.setAutoFlushEventListeners( new AutoFlushEventListener[] { EJB3AutoFlushEventListener.INSTANCE } );
listenerConfig.setDeleteEventListeners( new DeleteEventListener[] { new EJB3DeleteEventListener() } );
listenerConfig.setFlushEntityEventListeners(
new FlushEntityEventListener[] { new EJB3FlushEntityEventListener() }
);
listenerConfig.setMergeEventListeners( new MergeEventListener[] { new EJB3MergeEventListener() } );
listenerConfig.setPersistEventListeners( new PersistEventListener[] { new EJB3PersistEventListener() } );
listenerConfig.setPersistOnFlushEventListeners(
new PersistEventListener[] { new EJB3PersistOnFlushEventListener() }
);
listenerConfig.setSaveEventListeners( new SaveOrUpdateEventListener[] { new EJB3SaveEventListener() } );
listenerConfig.setSaveOrUpdateEventListeners(
new SaveOrUpdateEventListener[] { new EJB3SaveOrUpdateEventListener() }
);
//Pre events
listenerConfig.setPreInsertEventListeners(
new PreInsertEventListener[] {
new JACCPreInsertEventListener(),
}
);
listenerConfig.setPreUpdateEventListeners(
new PreUpdateEventListener[] {
new JACCPreUpdateEventListener(),
}
);
listenerConfig.setPreDeleteEventListeners(
new PreDeleteEventListener[] {
new JACCPreDeleteEventListener()
}
);
//Add the default Hibernate Core PreLoadEventListener
//TODO shouldn't we read the value from getPreLoadEventListeners and add JACC?
//probably a better thing to do as it allows cfg.xml config but this is a big change and need more thoughts
listenerConfig.setPreLoadEventListeners(
new PreLoadEventListener[] {
new DefaultPreLoadEventListener(),
new JACCPreLoadEventListener()
}
);
//post events
listenerConfig.setPostDeleteEventListeners(
new PostDeleteEventListener[] { new EJB3PostDeleteEventListener() }
);
listenerConfig.setPostInsertEventListeners(
new PostInsertEventListener[] { new EJB3PostInsertEventListener() }
);
//Add the default Hibernate Core PostLoadEventListener
//TODO shouldn't we read the value from getPostLoadEventListeners
//probably a better thing to do as it allows cfg.xml config but this is a big change and need more thoughts
listenerConfig.setPostLoadEventListeners(
new PostLoadEventListener[] { new EJB3PostLoadEventListener(), new DefaultPostLoadEventListener() }
);
EJB3PostUpdateEventListener postUpdateEventListener = new EJB3PostUpdateEventListener();
listenerConfig.setPostUpdateEventListeners(
new PostUpdateEventListener[] { postUpdateEventListener }
);
// EJB-288 - registration of post collection listeners. Commented out due to problem
// of duplicated callbacks. See Jira.
// listenerConfig.setPostCollectionRecreateEventListeners(
// new PostCollectionRecreateEventListener[] { postUpdateEventListener });
//
// listenerConfig.setPostCollectionRemoveEventListeners(
// new PostCollectionRemoveEventListener[] { postUpdateEventListener });
//
// listenerConfig.setPostCollectionUpdateEventListeners(
// new PostCollectionUpdateEventListener[] { postUpdateEventListener });
}
public void setProperties(Properties properties) {
if ( properties.containsKey( AvailableSettings.JACC_ENABLED ) ) {
isSecurity = true;
}
//override events if needed
Enumeration<?> enumeration = properties.propertyNames();
while ( enumeration.hasMoreElements() ) {
String name = (String) enumeration.nextElement();
if ( name.startsWith( AvailableSettings.EVENT_LISTENER_PREFIX ) ) {
String type = name.substring( AvailableSettings.EVENT_LISTENER_PREFIX.length() + 1 );
StringTokenizer st = new StringTokenizer( properties.getProperty( name ), " ,", false );
List<String> listeners = new ArrayList<String>();
while ( st.hasMoreElements() ) {
listeners.add( (String) st.nextElement() );
}
configuration.setListeners( type, listeners.toArray( new String[listeners.size()] ) );
}
}
}
@SuppressWarnings("unchecked")
public void configure() {
//TODO exclude pure hbm file classes?
//TODO move it to each event listener initialize()?
EntityCallbackHandler callbackHandler = new EntityCallbackHandler();
configuration.buildMappings(); //needed to get all the classes
Iterator classes = configuration.getClassMappings();
ReflectionManager reflectionManager = configuration.getHibernateConfiguration().getReflectionManager();
while ( classes.hasNext() ) {
PersistentClass clazz = (PersistentClass) classes.next();
if ( clazz.getClassName() != null ) {
//we can have non java class persisted by hibernate
try {
callbackHandler.add( reflectionManager.classForName( clazz.getClassName(), this.getClass() ), reflectionManager );
}
catch (ClassNotFoundException e) {
throw new MappingException( "entity class not found: " + clazz.getNodeName(), e );
}
}
}
EventListeners listenerConfig = configuration.getEventListeners();
BeanInfo beanInfo = null;
try {
beanInfo = Introspector.getBeanInfo( listenerConfig.getClass(), Object.class );
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
try {
for (int i = 0, max = pds.length; i < max; i++) {
final Object listeners = pds[i].getReadMethod().invoke( listenerConfig, READER_METHOD_ARGS );
if ( listeners == null ) {
throw new HibernateException( "Listener [" + pds[i].getName() + "] was null" );
}
if ( listeners instanceof Object[] ) {
int securityListenersNbr = 0;
Object[] listenersArray = (Object[]) listeners;
for (Object listener : listenersArray) {
if ( listener != null && listener instanceof CallbackHandlerConsumer ) {
( (CallbackHandlerConsumer) listener ).setCallbackHandler( callbackHandler );
}
if ( listener != null && listener instanceof JACCSecurityListener ) {
if ( !isSecurity ) {
securityListenersNbr++;
}
}
}
if ( !isSecurity ) {
Class clazz = pds[i].getReadMethod().getReturnType().getComponentType();
Object newArray = Array.newInstance( clazz, listenersArray.length - securityListenersNbr );
int index = 0;
for (Object listener : listenersArray) {
if ( !( listener != null && listener instanceof JACCSecurityListener ) ) {
Array.set( newArray, index++, listener );
}
}
pds[i].getWriteMethod().invoke( listenerConfig, newArray );
}
}
}
}
catch (HibernateException e) {
throw e;
}
catch (Throwable t) {
throw new HibernateException( "Unable to validate listener config", t );
}
}
catch (Exception t) {
throw new HibernateException( "Unable to copy listeners", t );
}
finally {
if ( beanInfo != null ) {
// release the jdk internal caches everytime to ensure this
// plays nicely with destroyable class-loaders
Introspector.flushFromCaches( getClass() );
}
}
}
}

View File

@ -1,8 +1,10 @@
/*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, 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 Middleware LLC.
* 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
@ -20,6 +22,7 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.event;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

View File

@ -1,8 +1,10 @@
/*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, 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 Middleware LLC.
* 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
@ -29,6 +31,7 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.hibernate.internal.util.ReflectHelper;
/**

View File

@ -1,8 +1,10 @@
/*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, 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 Middleware LLC.
* 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
@ -21,10 +23,9 @@
*/
package org.hibernate.ejb.event;
/**
* @author Emmanuel Bernard
*/
public interface CallbackHandlerConsumer {
public interface CallbackHandlerConsumer extends HibernateEntityManagerEventListener {
void setCallbackHandler(EntityCallbackHandler callbackHandler);
}

View File

@ -1,8 +1,10 @@
/*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, 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 Middleware LLC.
* 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
@ -20,23 +22,26 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.event;
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.ExcludeDefaultListeners;
import javax.persistence.ExcludeSuperclassListeners;
import javax.persistence.MappedSuperclass;
import javax.persistence.PersistenceException;
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.jboss.logging.Logger;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XMethod;
import org.hibernate.ejb.EntityManagerLogger;
import org.jboss.logging.Logger;
/**
* @author <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>

View File

@ -1,8 +1,10 @@
/*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, 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 Middleware LLC.
* 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
@ -20,19 +22,21 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.event;
import org.hibernate.engine.CascadingAction;
import org.hibernate.event.AutoFlushEventListener;
import org.hibernate.event.def.DefaultAutoFlushEventListener;
import org.hibernate.internal.util.collections.IdentityMap;
/**
* In EJB3, it is the create operation that is cascaded to unmanaged
* entities at flush time (instead of the save-update operation in
* Hibernate).
* In JPA, it is the create operation that is cascaded to unmanaged entities at flush time (instead of the save-update
* operation in Hibernate).
*
* @author Gavin King
*/
public class EJB3AutoFlushEventListener extends DefaultAutoFlushEventListener {
public class EJB3AutoFlushEventListener
extends DefaultAutoFlushEventListener
implements HibernateEntityManagerEventListener {
public static final AutoFlushEventListener INSTANCE = new EJB3AutoFlushEventListener();

View File

@ -1,8 +1,10 @@
/*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, 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 Middleware LLC.
* 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
@ -20,7 +22,9 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.event;
import java.io.Serializable;
import org.hibernate.event.DeleteEvent;
import org.hibernate.event.EventSource;
import org.hibernate.event.def.DefaultDeleteEventListener;

View File

@ -1,8 +1,10 @@
/*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, 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 Middleware LLC.
* 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
@ -20,6 +22,7 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.event;
import org.hibernate.EntityMode;
import org.hibernate.SessionFactory;
import org.hibernate.engine.EntityEntry;
@ -53,8 +56,11 @@ public class EJB3FlushEntityEventListener extends DefaultFlushEntityEventListene
@Override
protected boolean invokeInterceptor(
SessionImplementor session, Object entity, EntityEntry entry, Object[] values, EntityPersister persister
) {
SessionImplementor session,
Object entity,
EntityEntry entry,
Object[] values,
EntityPersister persister) {
boolean isDirty = false;
if ( entry.getStatus() != Status.DELETED ) {
if ( callbackHandler.preUpdate( entity ) ) {
@ -64,10 +70,8 @@ public class EJB3FlushEntityEventListener extends DefaultFlushEntityEventListene
return super.invokeInterceptor( session, entity, entry, values, persister ) || isDirty;
}
/**
* copy the entity state into the state array and return true if the state has changed
*/
private boolean copyState(Object entity, Type[] types, Object[] state, SessionFactory sf) {
// copy the entity state into the state array and return true if the state has changed
ClassMetadata metadata = sf.getClassMetadata( entity.getClass() );
Object[] newState = metadata.getPropertyValues( entity, EntityMode.POJO );
int size = newState.length;

View File

@ -1,8 +1,10 @@
/*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, 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 Middleware LLC.
* 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
@ -20,19 +22,19 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.event;
import org.hibernate.engine.CascadingAction;
import org.hibernate.event.FlushEventListener;
import org.hibernate.event.def.DefaultFlushEventListener;
import org.hibernate.internal.util.collections.IdentityMap;
/**
* In EJB3, it is the create operation that is cascaded to unmanaged
* ebtities at flush time (instead of the save-update operation in
* Hibernate).
* In EJB3, it is the create operation that is cascaded to unmanaged entities at flush time (instead of the
* save-update operation in Hibernate).
*
* @author Gavin King
*/
public class EJB3FlushEventListener extends DefaultFlushEventListener {
public class EJB3FlushEventListener extends DefaultFlushEventListener implements HibernateEntityManagerEventListener {
public static final FlushEventListener INSTANCE = new EJB3FlushEventListener();

View File

@ -1,8 +1,10 @@
/*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, 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 Middleware LLC.
* 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
@ -20,7 +22,9 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.event;
import java.io.Serializable;
import org.hibernate.event.EventSource;
import org.hibernate.event.def.DefaultMergeEventListener;
@ -46,18 +50,24 @@ public class EJB3MergeEventListener extends DefaultMergeEventListener implements
}
@Override
protected Serializable saveWithRequestedId(Object entity, Serializable requestedId, String entityName,
Object anything, EventSource source) {
protected Serializable saveWithRequestedId(
Object entity,
Serializable requestedId,
String entityName,
Object anything,
EventSource source) {
callbackHandler.preCreate( entity );
return super.saveWithRequestedId( entity, requestedId, entityName, anything,
source );
return super.saveWithRequestedId( entity, requestedId, entityName, anything, source );
}
@Override
protected Serializable saveWithGeneratedId(Object entity, String entityName, Object anything, EventSource source,
protected Serializable saveWithGeneratedId(
Object entity,
String entityName,
Object anything,
EventSource source,
boolean requiresImmediateIdAccess) {
callbackHandler.preCreate( entity );
return super.saveWithGeneratedId( entity, entityName, anything, source,
requiresImmediateIdAccess );
return super.saveWithGeneratedId( entity, entityName, anything, source, requiresImmediateIdAccess );
}
}

View File

@ -1,8 +1,10 @@
/*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, 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 Middleware LLC.
* 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
@ -20,7 +22,9 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.event;
import java.io.Serializable;
import org.hibernate.engine.CascadingAction;
import org.hibernate.engine.EJB3CascadeStyle;
import org.hibernate.engine.EJB3CascadingAction;
@ -53,19 +57,25 @@ public class EJB3PersistEventListener extends DefaultPersistEventListener implem
}
@Override
protected Serializable saveWithRequestedId(Object entity, Serializable requestedId, String entityName,
Object anything, EventSource source) {
protected Serializable saveWithRequestedId(
Object entity,
Serializable requestedId,
String entityName,
Object anything,
EventSource source) {
callbackHandler.preCreate( entity );
return super.saveWithRequestedId( entity, requestedId, entityName, anything,
source );
return super.saveWithRequestedId( entity, requestedId, entityName, anything, source );
}
@Override
protected Serializable saveWithGeneratedId(Object entity, String entityName, Object anything, EventSource source,
protected Serializable saveWithGeneratedId(
Object entity,
String entityName,
Object anything,
EventSource source,
boolean requiresImmediateIdAccess) {
callbackHandler.preCreate( entity );
return super.saveWithGeneratedId( entity, entityName, anything, source,
requiresImmediateIdAccess );
return super.saveWithGeneratedId( entity, entityName, anything, source, requiresImmediateIdAccess );
}
@Override

View File

@ -1,8 +1,10 @@
/*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, 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 Middleware LLC.
* 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
@ -20,6 +22,7 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.event;
import org.hibernate.engine.CascadingAction;
/**

View File

@ -1,8 +1,10 @@
/*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, 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 Middleware LLC.
* 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
@ -20,6 +22,7 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.event;
import org.hibernate.event.PostDeleteEvent;
import org.hibernate.event.PostDeleteEventListener;

View File

@ -1,8 +1,10 @@
/*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, 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 Middleware LLC.
* 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
@ -20,6 +22,7 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.event;
import org.hibernate.event.PostInsertEvent;
import org.hibernate.event.PostInsertEventListener;

View File

@ -1,8 +1,10 @@
/*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, 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 Middleware LLC.
* 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
@ -20,6 +22,7 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.event;
import org.hibernate.event.PostLoadEvent;
import org.hibernate.event.PostLoadEventListener;

View File

@ -1,8 +1,10 @@
/*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, 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 Middleware LLC.
* 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
@ -20,6 +22,7 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.event;
import org.hibernate.engine.EntityEntry;
import org.hibernate.engine.Status;
import org.hibernate.event.EventSource;
@ -38,9 +41,12 @@ import org.hibernate.event.PostUpdateEventListener;
* @author <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
*/
@SuppressWarnings("serial")
public class EJB3PostUpdateEventListener implements PostUpdateEventListener,
CallbackHandlerConsumer, PostCollectionRecreateEventListener,
PostCollectionRemoveEventListener, PostCollectionUpdateEventListener {
public class EJB3PostUpdateEventListener
implements PostUpdateEventListener,
CallbackHandlerConsumer,
PostCollectionRecreateEventListener,
PostCollectionRemoveEventListener,
PostCollectionUpdateEventListener {
EntityCallbackHandler callbackHandler;
public void setCallbackHandler(EntityCallbackHandler callbackHandler) {

View File

@ -1,8 +1,10 @@
/*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, 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 Middleware LLC.
* 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
@ -20,7 +22,9 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.event;
import java.io.Serializable;
import org.hibernate.event.EventSource;
import org.hibernate.event.def.DefaultSaveEventListener;
@ -46,18 +50,24 @@ public class EJB3SaveEventListener extends DefaultSaveEventListener implements C
}
@Override
protected Serializable saveWithRequestedId(Object entity, Serializable requestedId, String entityName,
Object anything, EventSource source) {
protected Serializable saveWithRequestedId(
Object entity,
Serializable requestedId,
String entityName,
Object anything,
EventSource source) {
callbackHandler.preCreate( entity );
return super.saveWithRequestedId( entity, requestedId, entityName, anything,
source );
return super.saveWithRequestedId( entity, requestedId, entityName, anything, source );
}
@Override
protected Serializable saveWithGeneratedId(Object entity, String entityName, Object anything, EventSource source,
protected Serializable saveWithGeneratedId(
Object entity,
String entityName,
Object anything,
EventSource source,
boolean requiresImmediateIdAccess) {
callbackHandler.preCreate( entity );
return super.saveWithGeneratedId( entity, entityName, anything, source,
requiresImmediateIdAccess );
return super.saveWithGeneratedId( entity, entityName, anything, source, requiresImmediateIdAccess );
}
}

View File

@ -1,8 +1,10 @@
/*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, 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 Middleware LLC.
* 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
@ -20,7 +22,9 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.event;
import java.io.Serializable;
import org.hibernate.event.EventSource;
import org.hibernate.event.def.DefaultSaveOrUpdateEventListener;
@ -46,18 +50,24 @@ public class EJB3SaveOrUpdateEventListener extends DefaultSaveOrUpdateEventListe
}
@Override
protected Serializable saveWithRequestedId(Object entity, Serializable requestedId, String entityName,
Object anything, EventSource source) {
protected Serializable saveWithRequestedId(
Object entity,
Serializable requestedId,
String entityName,
Object anything,
EventSource source) {
callbackHandler.preCreate( entity );
return super.saveWithRequestedId( entity, requestedId, entityName, anything,
source );
return super.saveWithRequestedId( entity, requestedId, entityName, anything, source );
}
@Override
protected Serializable saveWithGeneratedId(Object entity, String entityName, Object anything, EventSource source,
protected Serializable saveWithGeneratedId(
Object entity,
String entityName,
Object anything,
EventSource source,
boolean requiresImmediateIdAccess) {
callbackHandler.preCreate( entity );
return super.saveWithGeneratedId( entity, entityName, anything, source,
requiresImmediateIdAccess );
return super.saveWithGeneratedId( entity, entityName, anything, source, requiresImmediateIdAccess );
}
}

View File

@ -1,8 +1,10 @@
/*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, 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 Middleware LLC.
* 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
@ -20,8 +22,7 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.event;
import java.io.Serializable;
import java.util.HashMap;
import javax.persistence.PostLoad;
import javax.persistence.PostPersist;
import javax.persistence.PostRemove;
@ -29,6 +30,9 @@ import javax.persistence.PostUpdate;
import javax.persistence.PrePersist;
import javax.persistence.PreRemove;
import javax.persistence.PreUpdate;
import java.io.Serializable;
import java.util.HashMap;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.annotations.common.reflection.XClass;

View File

@ -0,0 +1,32 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.ejb.event;
/**
* Marker interface for handling listener duplication checking (to avoid multiple registrations).
*
* @author Steve Ebersole
*/
public interface HibernateEntityManagerEventListener {
}

View File

@ -0,0 +1,170 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.ejb.event;
import java.util.Iterator;
import java.util.Map;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.cfg.Mappings;
import org.hibernate.ejb.AvailableSettings;
import org.hibernate.event.EventListenerRegistration;
import org.hibernate.event.EventType;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.secure.JACCPreDeleteEventListener;
import org.hibernate.secure.JACCPreInsertEventListener;
import org.hibernate.secure.JACCPreLoadEventListener;
import org.hibernate.secure.JACCPreUpdateEventListener;
import org.hibernate.secure.JACCSecurityListener;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.event.spi.DuplicationStrategy;
import org.hibernate.service.event.spi.EventListenerGroup;
import org.hibernate.service.event.spi.EventListenerRegistry;
import org.hibernate.service.spi.ServiceRegistry;
/**
* Prepare the HEM-specific event listeners.
*
* @todo : tie this in with the "service locator" pattern defined by HHH-5562
*
* @author Steve Ebersole
*/
public class JpaEventListenerRegistration implements EventListenerRegistration {
private static final DuplicationStrategy JPA_DUPLICATION_STRATEGY = new DuplicationStrategy() {
@Override
public boolean areMatch(Object listener, Object original) {
return listener.getClass().equals( original.getClass() ) &&
HibernateEntityManagerEventListener.class.isInstance( original );
}
@Override
public Action getAction() {
return Action.KEEP_ORIGINAL;
}
};
private static final DuplicationStrategy JACC_DUPLICATION_STRATEGY = new DuplicationStrategy() {
@Override
public boolean areMatch(Object listener, Object original) {
return listener.getClass().equals( original.getClass() ) &&
JACCSecurityListener.class.isInstance( original );
}
@Override
public Action getAction() {
return Action.KEEP_ORIGINAL;
}
};
@Override
@SuppressWarnings( {"unchecked"})
public void apply(ServiceRegistry serviceRegistry, Mappings mappings, Map<?,?> configValues) {
boolean isSecurityEnabled = configValues.containsKey( AvailableSettings.JACC_ENABLED );
EventListenerRegistry eventListenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );
eventListenerRegistry.addDuplicationStrategy( JPA_DUPLICATION_STRATEGY );
eventListenerRegistry.addDuplicationStrategy( JACC_DUPLICATION_STRATEGY );
// op listeners
eventListenerRegistry.setListeners( EventType.AUTO_FLUSH, EJB3AutoFlushEventListener.INSTANCE );
eventListenerRegistry.setListeners( EventType.DELETE, new EJB3DeleteEventListener() );
eventListenerRegistry.setListeners( EventType.FLUSH_ENTITY, new EJB3FlushEntityEventListener() );
eventListenerRegistry.setListeners( EventType.FLUSH, EJB3FlushEventListener.INSTANCE );
eventListenerRegistry.setListeners( EventType.MERGE, new EJB3MergeEventListener() );
eventListenerRegistry.setListeners( EventType.PERSIST, new EJB3PersistEventListener() );
eventListenerRegistry.setListeners( EventType.PERSIST_ONFLUSH, new EJB3PersistOnFlushEventListener() );
eventListenerRegistry.setListeners( EventType.SAVE, new EJB3SaveEventListener() );
eventListenerRegistry.setListeners( EventType.SAVE_UPDATE, new EJB3SaveOrUpdateEventListener() );
// pre op listeners
if ( isSecurityEnabled ) {
eventListenerRegistry.prependListeners( EventType.PRE_DELETE, new JACCPreDeleteEventListener() );
eventListenerRegistry.prependListeners( EventType.PRE_INSERT, new JACCPreInsertEventListener() );
eventListenerRegistry.prependListeners( EventType.PRE_UPDATE, new JACCPreUpdateEventListener() );
eventListenerRegistry.prependListeners( EventType.PRE_LOAD, new JACCPreLoadEventListener() );
}
// post op listeners
eventListenerRegistry.prependListeners( EventType.POST_DELETE, new EJB3PostDeleteEventListener() );
eventListenerRegistry.prependListeners( EventType.POST_INSERT, new EJB3PostInsertEventListener() );
eventListenerRegistry.prependListeners( EventType.POST_LOAD, new EJB3PostLoadEventListener() );
eventListenerRegistry.prependListeners( EventType.POST_UPDATE, new EJB3PostUpdateEventListener() );
for ( Map.Entry<?,?> entry : configValues.entrySet() ) {
if ( ! String.class.isInstance( entry.getKey() ) ) {
continue;
}
final String propertyName = (String) entry.getKey();
if ( ! propertyName.startsWith( AvailableSettings.EVENT_LISTENER_PREFIX ) ) {
continue;
}
final String eventTypeName = propertyName.substring( AvailableSettings.EVENT_LISTENER_PREFIX.length() + 1 );
final EventType eventType = EventType.resolveEventTypeByName( eventTypeName );
final EventListenerGroup eventListenerGroup = eventListenerRegistry.getEventListenerGroup( eventType );
eventListenerGroup.clear();
for ( String listenerImpl : ( (String) entry.getValue() ).split( " ," ) ) {
eventListenerGroup.appendListener( instantiate( listenerImpl, serviceRegistry ) );
}
}
// todo : we may need to account for callback handlers previously set (shared across EMFs)
final EntityCallbackHandler callbackHandler = new EntityCallbackHandler();
Iterator classes = mappings.iterateClasses();
ReflectionManager reflectionManager = mappings.getReflectionManager();
while ( classes.hasNext() ) {
PersistentClass clazz = (PersistentClass) classes.next();
if ( clazz.getClassName() == null ) {
//we can have non java class persisted by hibernate
continue;
}
try {
callbackHandler.add( reflectionManager.classForName( clazz.getClassName(), this.getClass() ), reflectionManager );
}
catch (ClassNotFoundException e) {
throw new MappingException( "entity class not found: " + clazz.getNodeName(), e );
}
}
for ( EventType eventType : EventType.values() ) {
final EventListenerGroup eventListenerGroup = eventListenerRegistry.getEventListenerGroup( eventType );
for ( Object listener : eventListenerGroup.listeners() ) {
if ( CallbackHandlerConsumer.class.isInstance( listener ) ) {
( (CallbackHandlerConsumer) listener ).setCallbackHandler( callbackHandler );
}
}
}
}
private Object instantiate(String listenerImpl, ServiceRegistry serviceRegistry) {
try {
return serviceRegistry.getService( ClassLoaderService.class ).classForName( listenerImpl ).newInstance();
}
catch (Exception e) {
throw new HibernateException( "Could not instantiate requested listener [" + listenerImpl + "]", e );
}
}
}

View File

@ -1,8 +1,10 @@
/*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, 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 Middleware LLC.
* 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
@ -26,6 +28,7 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.hibernate.internal.util.ReflectHelper;
/**

View File

@ -56,8 +56,9 @@ import org.hibernate.ejb.test.pack.spacepar.Bug;
import org.hibernate.ejb.test.pack.various.Airplane;
import org.hibernate.ejb.test.pack.various.Seat;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.event.EventListeners;
import org.hibernate.event.EventType;
import org.hibernate.internal.util.ConfigHelper;
import org.hibernate.service.event.spi.EventListenerRegistry;
import org.hibernate.stat.Statistics;
import org.junit.Test;
@ -323,11 +324,13 @@ public class PackagedEntityManagerTest extends PackagingTestCase {
EntityManagerFactory emf = Persistence.createEntityManagerFactory( "manager1", new HashMap() );
EntityManager em = emf.createEntityManager();
EventListeners eventListeners = em.unwrap( SessionImplementor.class ).getListeners();
EventListenerRegistry listenerRegistry = em.unwrap( SessionImplementor.class ).getFactory()
.getServiceRegistry()
.getService( EventListenerRegistry.class );
assertEquals(
"Explicit pre-insert event through hibernate.ejb.event.pre-insert does not work",
eventListeners.getPreInsertEventListeners().length,
eventListeners.getPreUpdateEventListeners().length + 1
listenerRegistry.getEventListenerGroup( EventType.PRE_INSERT ).count(),
listenerRegistry.getEventListenerGroup( EventType.PRE_UPDATE ).count() + 1
);
em.close();

View File

@ -220,10 +220,6 @@ public abstract class AbstractDelegateSessionImplementor implements SessionImple
return delegate.getDontFlushFromFind();
}
public EventListeners getListeners() {
return delegate.getListeners();
}
public PersistenceContext getPersistenceContext() {
return delegate.getPersistenceContext();
}

View File

@ -0,0 +1,243 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.envers.event;
import java.io.Serializable;
import java.util.List;
import org.hibernate.collection.PersistentCollection;
import org.hibernate.engine.CollectionEntry;
import org.hibernate.envers.RevisionType;
import org.hibernate.envers.configuration.AuditConfiguration;
import org.hibernate.envers.entities.EntityConfiguration;
import org.hibernate.envers.entities.RelationDescription;
import org.hibernate.envers.entities.mapper.PersistentCollectionChangeData;
import org.hibernate.envers.entities.mapper.id.IdMapper;
import org.hibernate.envers.synchronization.AuditProcess;
import org.hibernate.envers.synchronization.work.AuditWorkUnit;
import org.hibernate.envers.synchronization.work.CollectionChangeWorkUnit;
import org.hibernate.envers.synchronization.work.FakeBidirectionalRelationWorkUnit;
import org.hibernate.envers.synchronization.work.PersistentCollectionChangeWorkUnit;
import org.hibernate.event.AbstractCollectionEvent;
import org.hibernate.persister.collection.AbstractCollectionPersister;
/**
* Base class for Envers' collection event related listeners
*
* @author Adam Warski (adam at warski dot org)
* @author Hern<EFBFBD>n Chanfreau
* @author Steve Ebersole
*/
public abstract class BaseEnversCollectionEventListener extends BaseEnversEventListener {
protected BaseEnversCollectionEventListener(AuditConfiguration enversConfiguration) {
super( enversConfiguration );
}
protected final CollectionEntry getCollectionEntry(AbstractCollectionEvent event) {
return event.getSession().getPersistenceContext().getCollectionEntry(event.getCollection());
}
protected final void onCollectionAction(
AbstractCollectionEvent event,
PersistentCollection newColl,
Serializable oldColl,
CollectionEntry collectionEntry) {
String entityName = event.getAffectedOwnerEntityName();
if ( ! enversConfiguration().getGlobalCfg().isGenerateRevisionsForCollections() ) {
return;
}
if ( enversConfiguration().getEntCfg().isVersioned( entityName ) ) {
AuditProcess auditProcess = enversConfiguration().getSyncManager().get(event.getSession());
String ownerEntityName = ((AbstractCollectionPersister) collectionEntry.getLoadedPersister()).getOwnerEntityName();
String referencingPropertyName = collectionEntry.getRole().substring(ownerEntityName.length() + 1);
// Checking if this is not a "fake" many-to-one bidirectional relation. The relation description may be
// null in case of collections of non-entities.
RelationDescription rd = searchForRelationDescription( entityName, referencingPropertyName );
if ( rd != null && rd.getMappedByPropertyName() != null ) {
generateFakeBidirecationalRelationWorkUnits(
auditProcess,
newColl,
oldColl,
entityName,
referencingPropertyName,
event,
rd
);
}
else {
PersistentCollectionChangeWorkUnit workUnit = new PersistentCollectionChangeWorkUnit(
event.getSession(),
entityName,
enversConfiguration(),
newColl,
collectionEntry,
oldColl,
event.getAffectedOwnerIdOrNull(),
referencingPropertyName
);
auditProcess.addWorkUnit( workUnit );
if (workUnit.containsWork()) {
// There are some changes: a revision needs also be generated for the collection owner
auditProcess.addWorkUnit(
new CollectionChangeWorkUnit(
event.getSession(),
event.getAffectedOwnerEntityName(),
enversConfiguration(),
event.getAffectedOwnerIdOrNull(),
event.getAffectedOwnerOrNull()
)
);
generateBidirectionalCollectionChangeWorkUnits( auditProcess, event, workUnit, rd );
}
}
}
}
/**
* Looks up a relation description corresponding to the given property in the given entity. If no description is
* found in the given entity, the parent entity is checked (so that inherited relations work).
*
* @param entityName Name of the entity, in which to start looking.
* @param referencingPropertyName The name of the property.
*
* @return A found relation description corresponding to the given entity or {@code null}, if no description can
* be found.
*/
private RelationDescription searchForRelationDescription(String entityName, String referencingPropertyName) {
EntityConfiguration configuration = enversConfiguration().getEntCfg().get( entityName );
RelationDescription rd = configuration.getRelationDescription(referencingPropertyName);
if ( rd == null && configuration.getParentEntityName() != null ) {
return searchForRelationDescription( configuration.getParentEntityName(), referencingPropertyName );
}
return rd;
}
private void generateFakeBidirecationalRelationWorkUnits(
AuditProcess auditProcess,
PersistentCollection newColl,
Serializable oldColl,
String collectionEntityName,
String referencingPropertyName,
AbstractCollectionEvent event,
RelationDescription rd) {
// First computing the relation changes
List<PersistentCollectionChangeData> collectionChanges = enversConfiguration()
.getEntCfg()
.get( collectionEntityName )
.getPropertyMapper()
.mapCollectionChanges( referencingPropertyName, newColl, oldColl, event.getAffectedOwnerIdOrNull() );
// Getting the id mapper for the related entity, as the work units generated will corrspond to the related
// entities.
String relatedEntityName = rd.getToEntityName();
IdMapper relatedIdMapper = enversConfiguration().getEntCfg().get(relatedEntityName).getIdMapper();
// For each collection change, generating the bidirectional work unit.
for ( PersistentCollectionChangeData changeData : collectionChanges ) {
Object relatedObj = changeData.getChangedElement();
Serializable relatedId = (Serializable) relatedIdMapper.mapToIdFromEntity(relatedObj);
RevisionType revType = (RevisionType) changeData.getData().get(
enversConfiguration().getAuditEntCfg().getRevisionTypePropName()
);
// This can be different from relatedEntityName, in case of inheritance (the real entity may be a subclass
// of relatedEntityName).
String realRelatedEntityName = event.getSession().bestGuessEntityName(relatedObj);
// By default, the nested work unit is a collection change work unit.
AuditWorkUnit nestedWorkUnit = new CollectionChangeWorkUnit(
event.getSession(),
realRelatedEntityName,
enversConfiguration(),
relatedId,
relatedObj
);
auditProcess.addWorkUnit(
new FakeBidirectionalRelationWorkUnit(
event.getSession(),
realRelatedEntityName,
enversConfiguration(),
relatedId,
referencingPropertyName,
event.getAffectedOwnerOrNull(),
rd,
revType,
changeData.getChangedElementIndex(),
nestedWorkUnit
)
);
}
// We also have to generate a collection change work unit for the owning entity.
auditProcess.addWorkUnit(
new CollectionChangeWorkUnit(
event.getSession(),
collectionEntityName,
enversConfiguration(),
event.getAffectedOwnerIdOrNull(),
event.getAffectedOwnerOrNull()
)
);
}
private void generateBidirectionalCollectionChangeWorkUnits(
AuditProcess auditProcess,
AbstractCollectionEvent event,
PersistentCollectionChangeWorkUnit workUnit,
RelationDescription rd) {
// Checking if this is enabled in configuration ...
if ( ! enversConfiguration().getGlobalCfg().isGenerateRevisionsForCollections() ) {
return;
}
// Checking if this is not a bidirectional relation - then, a revision needs also be generated for
// the other side of the relation.
// relDesc can be null if this is a collection of simple values (not a relation).
if ( rd != null && rd.isBidirectional() ) {
String relatedEntityName = rd.getToEntityName();
IdMapper relatedIdMapper = enversConfiguration().getEntCfg().get( relatedEntityName ).getIdMapper();
for ( PersistentCollectionChangeData changeData : workUnit.getCollectionChanges() ) {
Object relatedObj = changeData.getChangedElement();
Serializable relatedId = (Serializable) relatedIdMapper.mapToIdFromEntity( relatedObj );
auditProcess.addWorkUnit(
new CollectionChangeWorkUnit(
event.getSession(),
relatedEntityName,
enversConfiguration(),
relatedId,
relatedObj
)
);
}
}
}
}

View File

@ -0,0 +1,132 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.envers.event;
import java.io.Serializable;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.envers.configuration.AuditConfiguration;
import org.hibernate.envers.entities.RelationDescription;
import org.hibernate.envers.entities.RelationType;
import org.hibernate.envers.entities.mapper.id.IdMapper;
import org.hibernate.envers.synchronization.AuditProcess;
import org.hibernate.envers.synchronization.work.CollectionChangeWorkUnit;
import org.hibernate.envers.tools.Tools;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.proxy.HibernateProxy;
/**
* Base class for all Envers event listeners
*
* @author Adam Warski (adam at warski dot org)
* @author Hern<EFBFBD>n Chanfreau
* @author Steve Ebersole
*/
public abstract class BaseEnversEventListener implements EnversListener {
private AuditConfiguration enversConfiguration;
protected BaseEnversEventListener(AuditConfiguration enversConfiguration) {
this.enversConfiguration = enversConfiguration;
}
protected AuditConfiguration enversConfiguration() {
return enversConfiguration;
}
protected final void generateBidirectionalCollectionChangeWorkUnits(
AuditProcess auditProcess,
EntityPersister entityPersister,
String entityName,
Object[] newState,
Object[] oldState,
SessionImplementor session) {
// Checking if this is enabled in configuration ...
if ( ! enversConfiguration.getGlobalCfg().isGenerateRevisionsForCollections() ) {
return;
}
// Checks every property of the entity, if it is an "owned" to-one relation to another entity.
// If the value of that property changed, and the relation is bi-directional, a new revision
// for the related entity is generated.
String[] propertyNames = entityPersister.getPropertyNames();
for ( int i=0; i<propertyNames.length; i++ ) {
String propertyName = propertyNames[i];
RelationDescription relDesc = enversConfiguration.getEntCfg().getRelationDescription(entityName, propertyName);
if (relDesc != null && relDesc.isBidirectional() && relDesc.getRelationType() == RelationType.TO_ONE &&
relDesc.isInsertable()) {
// Checking for changes
Object oldValue = oldState == null ? null : oldState[i];
Object newValue = newState == null ? null : newState[i];
if (!Tools.entitiesEqual( session, relDesc.getToEntityName(), oldValue, newValue )) {
// We have to generate changes both in the old collection (size decreses) and new collection
// (size increases).
if (newValue != null) {
// relDesc.getToEntityName() doesn't always return the entity name of the value - in case
// of subclasses, this will be root class, no the actual class. So it can't be used here.
String toEntityName;
Serializable id;
if (newValue instanceof HibernateProxy ) {
HibernateProxy hibernateProxy = (HibernateProxy) newValue;
toEntityName = session.bestGuessEntityName(newValue);
id = hibernateProxy.getHibernateLazyInitializer().getIdentifier();
// We've got to initialize the object from the proxy to later read its state.
newValue = Tools.getTargetFromProxy(session.getFactory(), hibernateProxy);
} else {
toEntityName = session.guessEntityName(newValue);
IdMapper idMapper = enversConfiguration.getEntCfg().get(toEntityName).getIdMapper();
id = (Serializable) idMapper.mapToIdFromEntity(newValue);
}
auditProcess.addWorkUnit(new CollectionChangeWorkUnit(session, toEntityName, enversConfiguration, id, newValue));
}
if (oldValue != null) {
String toEntityName;
Serializable id;
if(oldValue instanceof HibernateProxy) {
HibernateProxy hibernateProxy = (HibernateProxy) oldValue;
toEntityName = session.bestGuessEntityName(oldValue);
id = hibernateProxy.getHibernateLazyInitializer().getIdentifier();
// We've got to initialize the object as we'll read it's state anyway.
oldValue = Tools.getTargetFromProxy(session.getFactory(), hibernateProxy);
} else {
toEntityName = session.guessEntityName(oldValue);
IdMapper idMapper = enversConfiguration.getEntCfg().get(toEntityName).getIdMapper();
id = (Serializable) idMapper.mapToIdFromEntity(oldValue);
}
auditProcess.addWorkUnit(new CollectionChangeWorkUnit(session, toEntityName, enversConfiguration, id, oldValue));
}
}
}
}
}
}

View File

@ -0,0 +1,58 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.envers.event;
import java.util.Map;
import org.hibernate.cfg.Mappings;
import org.hibernate.envers.configuration.AuditConfiguration;
import org.hibernate.event.EventListenerRegistration;
import org.hibernate.event.EventType;
import org.hibernate.service.event.spi.EventListenerRegistry;
import org.hibernate.service.spi.ServiceRegistry;
/**
* See "transitory" notes on {@link EventListenerRegistration}
*
* @author Steve Ebersole
*/
public class EnversEventListenerRegistration implements EventListenerRegistration {
@Override
public void apply(ServiceRegistry serviceRegistry, Mappings mappings, Map<?, ?> configValues) {
EventListenerRegistry listenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );
listenerRegistry.addDuplicationStrategy( EnversListenerDuplicationStrategy.INSTANCE );
// todo : build AuditConfiguration; requires massive changes...
// AuditConfiguration auditConfiguration = AuditConfiguration.getFor( ??? )
AuditConfiguration auditConfiguration = null;
// create/add listeners
listenerRegistry.appendListeners( EventType.POST_DELETE, new EnversPostDeleteEventListenerImpl( auditConfiguration ) );
listenerRegistry.appendListeners( EventType.POST_INSERT, new EnversPostInsertEventListenerImpl( auditConfiguration ) );
listenerRegistry.appendListeners( EventType.POST_UPDATE, new EnversPostUpdateEventListenerImpl( auditConfiguration ) );
listenerRegistry.appendListeners( EventType.POST_COLLECTION_RECREATE, new EnversPostCollectionRecreateEventListenerImpl( auditConfiguration ) );
listenerRegistry.appendListeners( EventType.PRE_COLLECTION_REMOVE, new EnversPreCollectionRemoveEventListenerImpl( auditConfiguration ) );
listenerRegistry.appendListeners( EventType.PRE_COLLECTION_UPDATE, new EnversPreCollectionUpdateEventListenerImpl( auditConfiguration ) );
}
}

View File

@ -0,0 +1,32 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.envers.event;
/**
* Marker interface for Envers listeners for duplication handling.
*
* @author Steve Ebersole
*/
public interface EnversListener {
}

View File

@ -0,0 +1,45 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.envers.event;
import org.hibernate.service.event.spi.DuplicationStrategy;
/**
* Event listener duplication strategy for envers
*
* @author Steve Ebersole
*/
public class EnversListenerDuplicationStrategy implements DuplicationStrategy {
public static final EnversListenerDuplicationStrategy INSTANCE = new EnversListenerDuplicationStrategy();
@Override
public boolean areMatch(Object listener, Object original) {
return listener.getClass().equals( original ) && EnversListener.class.isInstance( listener );
}
@Override
public Action getAction() {
return Action.KEEP_ORIGINAL;
}
}

View File

@ -0,0 +1,51 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.envers.event;
import org.hibernate.engine.CollectionEntry;
import org.hibernate.envers.configuration.AuditConfiguration;
import org.hibernate.event.PostCollectionRecreateEvent;
import org.hibernate.event.PostCollectionRecreateEventListener;
/**
* @author Adam Warski (adam at warski dot org)
* @author Hern<EFBFBD>n Chanfreau
* @author Steve Ebersole
*/
public class EnversPostCollectionRecreateEventListenerImpl
extends BaseEnversCollectionEventListener
implements PostCollectionRecreateEventListener {
protected EnversPostCollectionRecreateEventListenerImpl(AuditConfiguration enversConfiguration) {
super( enversConfiguration );
}
@Override
public void onPostRecreateCollection(PostCollectionRecreateEvent event) {
CollectionEntry collectionEntry = getCollectionEntry( event );
if ( ! collectionEntry.getLoadedPersister().isInverse() ) {
onCollectionAction( event, event.getCollection(), null, collectionEntry );
}
}
}

View File

@ -0,0 +1,72 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.envers.event;
import org.hibernate.envers.configuration.AuditConfiguration;
import org.hibernate.envers.synchronization.AuditProcess;
import org.hibernate.envers.synchronization.work.AuditWorkUnit;
import org.hibernate.envers.synchronization.work.DelWorkUnit;
import org.hibernate.event.PostDeleteEvent;
import org.hibernate.event.PostDeleteEventListener;
/**
* @author Adam Warski (adam at warski dot org)
* @author Hern<EFBFBD>n Chanfreau
* @author Steve Ebersole
*/
public class EnversPostDeleteEventListenerImpl extends BaseEnversEventListener implements PostDeleteEventListener {
protected EnversPostDeleteEventListenerImpl(AuditConfiguration enversConfiguration) {
super( enversConfiguration );
}
@Override
public void onPostDelete(PostDeleteEvent event) {
String entityName = event.getPersister().getEntityName();
if ( enversConfiguration().getEntCfg().isVersioned( entityName ) ) {
AuditProcess auditProcess = enversConfiguration().getSyncManager().get( event.getSession() );
AuditWorkUnit workUnit = new DelWorkUnit(
event.getSession(),
event.getPersister().getEntityName(),
enversConfiguration(),
event.getId(),
event.getPersister(),
event.getDeletedState()
);
auditProcess.addWorkUnit( workUnit );
if ( workUnit.containsWork() ) {
generateBidirectionalCollectionChangeWorkUnits(
auditProcess,
event.getPersister(),
entityName,
null,
event.getDeletedState(),
event.getSession()
);
}
}
}
}

View File

@ -0,0 +1,71 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.envers.event;
import org.hibernate.envers.configuration.AuditConfiguration;
import org.hibernate.envers.synchronization.AuditProcess;
import org.hibernate.envers.synchronization.work.AddWorkUnit;
import org.hibernate.envers.synchronization.work.AuditWorkUnit;
import org.hibernate.event.PostInsertEvent;
import org.hibernate.event.PostInsertEventListener;
/**
* @author Adam Warski (adam at warski dot org)
* @author Hern<EFBFBD>n Chanfreau
* @author Steve Ebersole
*/
public class EnversPostInsertEventListenerImpl extends BaseEnversEventListener implements PostInsertEventListener {
public EnversPostInsertEventListenerImpl(AuditConfiguration enversConfiguration) {
super( enversConfiguration );
}
public void onPostInsert(PostInsertEvent event) {
String entityName = event.getPersister().getEntityName();
if ( enversConfiguration().getEntCfg().isVersioned( entityName ) ) {
AuditProcess auditProcess = enversConfiguration().getSyncManager().get(event.getSession());
AuditWorkUnit workUnit = new AddWorkUnit(
event.getSession(),
event.getPersister().getEntityName(),
enversConfiguration(),
event.getId(),
event.getPersister(),
event.getState()
);
auditProcess.addWorkUnit( workUnit );
if ( workUnit.containsWork() ) {
generateBidirectionalCollectionChangeWorkUnits(
auditProcess,
event.getPersister(),
entityName,
event.getState(),
null,
event.getSession()
);
}
}
}
}

View File

@ -0,0 +1,73 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.envers.event;
import org.hibernate.envers.configuration.AuditConfiguration;
import org.hibernate.envers.synchronization.AuditProcess;
import org.hibernate.envers.synchronization.work.AuditWorkUnit;
import org.hibernate.envers.synchronization.work.ModWorkUnit;
import org.hibernate.event.PostUpdateEvent;
import org.hibernate.event.PostUpdateEventListener;
/**
* @author Adam Warski (adam at warski dot org)
* @author Hern<EFBFBD>n Chanfreau
* @author Steve Ebersole
*/
public class EnversPostUpdateEventListenerImpl extends BaseEnversEventListener implements PostUpdateEventListener {
protected EnversPostUpdateEventListenerImpl(AuditConfiguration enversConfiguration) {
super( enversConfiguration );
}
@Override
public void onPostUpdate(PostUpdateEvent event) {
String entityName = event.getPersister().getEntityName();
if ( enversConfiguration().getEntCfg().isVersioned(entityName) ) {
AuditProcess auditProcess = enversConfiguration().getSyncManager().get(event.getSession());
AuditWorkUnit workUnit = new ModWorkUnit(
event.getSession(),
event.getPersister().getEntityName(),
enversConfiguration(),
event.getId(),
event.getPersister(),
event.getState(),
event.getOldState()
);
auditProcess.addWorkUnit( workUnit );
if ( workUnit.containsWork() ) {
generateBidirectionalCollectionChangeWorkUnits(
auditProcess,
event.getPersister(),
entityName,
event.getState(),
event.getOldState(),
event.getSession()
);
}
}
}
}

View File

@ -0,0 +1,51 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.envers.event;
import org.hibernate.engine.CollectionEntry;
import org.hibernate.envers.configuration.AuditConfiguration;
import org.hibernate.event.PreCollectionRemoveEvent;
import org.hibernate.event.PreCollectionRemoveEventListener;
/**
* @author Adam Warski (adam at warski dot org)
* @author Hern<EFBFBD>n Chanfreau
* @author Steve Ebersole
*/
public class EnversPreCollectionRemoveEventListenerImpl
extends BaseEnversCollectionEventListener
implements PreCollectionRemoveEventListener {
protected EnversPreCollectionRemoveEventListenerImpl(AuditConfiguration enversConfiguration) {
super( enversConfiguration );
}
@Override
public void onPreRemoveCollection(PreCollectionRemoveEvent event) {
CollectionEntry collectionEntry = getCollectionEntry( event );
if ( collectionEntry != null && !collectionEntry.getLoadedPersister().isInverse() ) {
onCollectionAction( event, null, collectionEntry.getSnapshot(), collectionEntry );
}
}
}

View File

@ -0,0 +1,51 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.envers.event;
import org.hibernate.engine.CollectionEntry;
import org.hibernate.envers.configuration.AuditConfiguration;
import org.hibernate.event.PreCollectionUpdateEvent;
import org.hibernate.event.PreCollectionUpdateEventListener;
/**
* @author Adam Warski (adam at warski dot org)
* @author Hern<EFBFBD>n Chanfreau
* @author Steve Ebersole
*/
public class EnversPreCollectionUpdateEventListenerImpl
extends BaseEnversCollectionEventListener
implements PreCollectionUpdateEventListener {
protected EnversPreCollectionUpdateEventListenerImpl(AuditConfiguration enversConfiguration) {
super( enversConfiguration );
}
@Override
public void onPreUpdateCollection(PreCollectionUpdateEvent event) {
CollectionEntry collectionEntry = getCollectionEntry( event );
if ( ! collectionEntry.getLoadedPersister().isInverse() ) {
onCollectionAction( event, event.getCollection(), collectionEntry.getSnapshot(), collectionEntry );
}
}
}