diff --git a/hibernate-entitymanager/hibernate-entitymanager.gradle b/hibernate-entitymanager/hibernate-entitymanager.gradle
index c90834f6fc..fb219fe5a3 100644
--- a/hibernate-entitymanager/hibernate-entitymanager.gradle
+++ b/hibernate-entitymanager/hibernate-entitymanager.gradle
@@ -9,11 +9,16 @@ dependencies {
compile( libraries.jpa )
compile( libraries.jta )
compile( libraries.javassist )
+ provided( "javax.enterprise:cdi-api:1.0-SP4" )
testCompile( project(':hibernate-testing') )
testCompile( libraries.shrinkwrap_api )
testCompile( libraries.shrinkwrap )
testCompile( libraries.validation )
testRuntime( libraries.validator )
+ testCompile( "org.jboss.weld.arquillian.container:arquillian-weld-ee-embedded-1.1:1.1.2.Final" )
+ testCompile( "org.jboss.weld:weld-core:1.1.9.Final" )
+ testRuntime( "org.glassfish.web:el-impl:2.1.2-b04" )
+ testRuntime( "org.jboss.ejb3:jboss-ejb3-api:3.1.0" )
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/AvailableSettings.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/AvailableSettings.java
index b75fa98d85..35ea9ba54f 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/AvailableSettings.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/AvailableSettings.java
@@ -187,6 +187,11 @@ public interface AvailableSettings {
*/
public static final String REMOVE_VALIDATION_GROUP = "javax.persistence.validation.group.pre-remove";
+ /**
+ * Used to pass along the CDI BeanManager, if any, to be used.
+ */
+ public static final String CDI_BEAN_MANAGER = "javax.persistence.bean.manager";
+
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Hibernate specific settings
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/Callback.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/Callback.java
deleted file mode 100644
index 6c6a697968..0000000000
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/Callback.java
+++ /dev/null
@@ -1,90 +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.jpa.internal.event;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringTokenizer;
-
-import org.hibernate.internal.util.ReflectHelper;
-
-/**
- * @author Kabir Khan
- */
-public abstract class Callback implements Serializable {
- transient protected Method callbackMethod;
-
- public Callback(Method callbackMethod) {
- this.callbackMethod = callbackMethod;
- }
-
- public Method getCallbackMethod() {
- return callbackMethod;
- }
-
- public abstract void invoke(Object bean);
-
- private void writeObject(ObjectOutputStream oos) throws IOException {
- oos.defaultWriteObject();
- oos.writeObject( callbackMethod.toGenericString() );
- }
-
- private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
- ois.defaultReadObject();
- String signature = (String) ois.readObject();
- StringTokenizer st = new StringTokenizer( signature, " ", false );
- String usefulSignature = null;
- while ( st.hasMoreElements() ) usefulSignature = (String) st.nextElement();
- int parenthesis = usefulSignature.indexOf( "(" );
- String methodAndClass = usefulSignature.substring( 0, parenthesis );
- int lastDot = methodAndClass.lastIndexOf( "." );
- String clazzName = methodAndClass.substring( 0, lastDot );
- Class callbackClass = ReflectHelper.classForName( clazzName, this.getClass() );
- String parametersString = usefulSignature.substring( parenthesis + 1, usefulSignature.length() - 1 );
- st = new StringTokenizer( parametersString, ", ", false );
- List parameters = new ArrayList();
- while ( st.hasMoreElements() ) {
- String parameter = (String) st.nextElement();
- parameters.add( ReflectHelper.classForName( parameter, this.getClass() ) );
- }
- String methodName = methodAndClass.substring( lastDot + 1, methodAndClass.length() );
- try {
- callbackMethod = callbackClass.getDeclaredMethod(
- methodName,
- parameters.toArray( new Class[ parameters.size() ] )
- );
- if ( ! callbackMethod.isAccessible() ) {
- callbackMethod.setAccessible( true );
- }
- }
- catch (NoSuchMethodException e) {
- throw new IOException( "Unable to get EJB3 callback method: " + signature + ", cause: " + e );
- }
- }
-}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaIntegrator.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaIntegrator.java
index 5bc9ac4e6e..f4c17067f3 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaIntegrator.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaIntegrator.java
@@ -23,12 +23,11 @@
*/
package org.hibernate.jpa.internal.event;
+import javax.enterprise.inject.spi.BeanManager;
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.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.spi.CascadeStyles;
@@ -41,6 +40,28 @@ import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType;
import org.hibernate.integrator.spi.Integrator;
import org.hibernate.jpa.AvailableSettings;
+import org.hibernate.jpa.internal.event.core.HibernateEntityManagerEventListener;
+import org.hibernate.jpa.internal.event.core.JpaAutoFlushEventListener;
+import org.hibernate.jpa.internal.event.core.JpaDeleteEventListener;
+import org.hibernate.jpa.internal.event.core.JpaFlushEntityEventListener;
+import org.hibernate.jpa.internal.event.core.JpaFlushEventListener;
+import org.hibernate.jpa.internal.event.core.JpaMergeEventListener;
+import org.hibernate.jpa.internal.event.core.JpaPersistEventListener;
+import org.hibernate.jpa.internal.event.core.JpaPersistOnFlushEventListener;
+import org.hibernate.jpa.internal.event.core.JpaPostDeleteEventListener;
+import org.hibernate.jpa.internal.event.core.JpaPostInsertEventListener;
+import org.hibernate.jpa.internal.event.core.JpaPostLoadEventListener;
+import org.hibernate.jpa.internal.event.core.JpaPostUpdateEventListener;
+import org.hibernate.jpa.internal.event.core.JpaSaveEventListener;
+import org.hibernate.jpa.internal.event.core.JpaSaveOrUpdateEventListener;
+import org.hibernate.jpa.internal.event.jpa.BeanManagerListenerFactory;
+import org.hibernate.jpa.internal.event.jpa.CallbackProcessor;
+import org.hibernate.jpa.internal.event.jpa.CallbackProcessorImpl;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistryConsumer;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistry;
+import org.hibernate.jpa.internal.event.jpa.LegacyCallbackProcessor;
+import org.hibernate.jpa.internal.event.jpa.ListenerFactory;
+import org.hibernate.jpa.internal.event.jpa.StandardListenerFactory;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.source.MetadataImplementor;
@@ -50,16 +71,19 @@ import org.hibernate.secure.internal.JACCPreLoadEventListener;
import org.hibernate.secure.internal.JACCPreUpdateEventListener;
import org.hibernate.secure.internal.JACCSecurityListener;
import org.hibernate.service.classloading.spi.ClassLoaderService;
-import org.hibernate.service.classloading.spi.ClassLoadingException;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
/**
- * Prepare the HEM-specific event listeners.
+ * Hibernate EntityManager specific Integrator, performing JPA setup.
*
* @author Steve Ebersole
*/
public class JpaIntegrator implements Integrator {
+ private ListenerFactory jpaListenerFactory;
+ private CallbackProcessor callbackProcessor;
+ private CallbackRegistry callbackRegistry;
+
private static final DuplicationStrategy JPA_DUPLICATION_STRATEGY = new DuplicationStrategy() {
@Override
public boolean areMatch(Object listener, Object original) {
@@ -109,6 +133,7 @@ public class JpaIntegrator implements Integrator {
}
);
+
// then prepare listeners
final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );
@@ -159,28 +184,30 @@ public class JpaIntegrator implements Integrator {
}
}
- final EntityCallbackHandler callbackHandler = new EntityCallbackHandler();
+ // handle JPA "entity listener classes"...
+
+ this.callbackRegistry = new CallbackRegistry();
+ final BeanManager beanManager = (BeanManager) configuration.getProperties().get( AvailableSettings.CDI_BEAN_MANAGER );
+ this.jpaListenerFactory = beanManager == null
+ ? new StandardListenerFactory()
+ : new BeanManagerListenerFactory( beanManager );
+ this.callbackProcessor = new LegacyCallbackProcessor( jpaListenerFactory, configuration.getReflectionManager() );
+
Iterator classes = configuration.getClassMappings();
- ReflectionManager reflectionManager = configuration.getReflectionManager();
while ( classes.hasNext() ) {
- PersistentClass clazz = (PersistentClass) classes.next();
+ final PersistentClass clazz = (PersistentClass) classes.next();
if ( clazz.getClassName() == null ) {
- //we can have non java class persisted by hibernate
+ // 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 );
- }
+ callbackProcessor.processCallbacksForEntity( clazz.getClassName(), callbackRegistry );
}
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 );
+ if ( CallbackRegistryConsumer.class.isInstance( listener ) ) {
+ ( (CallbackRegistryConsumer) listener ).injectCallbackRegistry( callbackRegistry );
}
}
}
@@ -258,34 +285,40 @@ public class JpaIntegrator implements Integrator {
}
}
- final EntityCallbackHandler callbackHandler = new EntityCallbackHandler();
- ClassLoaderService classLoaderSvc = serviceRegistry.getService(ClassLoaderService.class);
- for (EntityBinding binding : metadata.getEntityBindings()) {
- String name = binding.getEntity().getName(); // Should this be getClassName()?
- if (name == null) {
- //we can have non java class persisted by hibernate
- continue;
- }
- try {
- callbackHandler.add(classLoaderSvc.classForName(name), classLoaderSvc, binding);
- }
- catch (ClassLoadingException error) {
- throw new MappingException( "entity class not found: " + name, error );
+ // handle JPA "entity listener classes"...
+
+ this.callbackRegistry = new CallbackRegistry();
+ final BeanManager beanManager = (BeanManager) sessionFactory.getProperties().get( AvailableSettings.CDI_BEAN_MANAGER );
+ this.jpaListenerFactory = beanManager == null
+ ? new StandardListenerFactory()
+ : new BeanManagerListenerFactory( beanManager );
+ this.callbackProcessor = new CallbackProcessorImpl( jpaListenerFactory, metadata, serviceRegistry );
+
+ for ( EntityBinding binding : metadata.getEntityBindings() ) {
+ callbackProcessor.processCallbacksForEntity( binding, callbackRegistry );
+ }
+
+ for ( EventType eventType : EventType.values() ) {
+ final EventListenerGroup eventListenerGroup = eventListenerRegistry.getEventListenerGroup( eventType );
+ for ( Object listener : eventListenerGroup.listeners() ) {
+ if ( CallbackRegistryConsumer.class.isInstance( listener ) ) {
+ ( (CallbackRegistryConsumer) listener ).injectCallbackRegistry( callbackRegistry );
+ }
}
}
-//
-// 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 );
-// }
-// }
-// }
}
@Override
public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
+ if ( callbackRegistry != null ) {
+ callbackRegistry.release();
+ }
+ if ( callbackProcessor != null ) {
+ callbackProcessor.release();
+ }
+ if ( jpaListenerFactory != null ) {
+ jpaListenerFactory.release();
+ }
}
private Object instantiate(String listenerImpl, ServiceRegistryImplementor serviceRegistry) {
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/HibernateEntityManagerEventListener.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/HibernateEntityManagerEventListener.java
similarity index 96%
rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/HibernateEntityManagerEventListener.java
rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/HibernateEntityManagerEventListener.java
index eb42886b10..4ddf11a78a 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/HibernateEntityManagerEventListener.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/HibernateEntityManagerEventListener.java
@@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.jpa.internal.event;
+package org.hibernate.jpa.internal.event.core;
/**
* Marker interface for handling listener duplication checking (to avoid multiple registrations).
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaAutoFlushEventListener.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaAutoFlushEventListener.java
similarity index 97%
rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaAutoFlushEventListener.java
rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaAutoFlushEventListener.java
index d95ce64369..8df21999a0 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaAutoFlushEventListener.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaAutoFlushEventListener.java
@@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.jpa.internal.event;
+package org.hibernate.jpa.internal.event.core;
import java.util.IdentityHashMap;
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaDeleteEventListener.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaDeleteEventListener.java
similarity index 80%
rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaDeleteEventListener.java
rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaDeleteEventListener.java
index 8c98271cc9..ac24a91bbd 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaDeleteEventListener.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaDeleteEventListener.java
@@ -21,13 +21,15 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.jpa.internal.event;
+package org.hibernate.jpa.internal.event.core;
import java.io.Serializable;
import org.hibernate.event.internal.DefaultDeleteEventListener;
import org.hibernate.event.spi.DeleteEvent;
import org.hibernate.event.spi.EventSource;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistryConsumer;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistry;
import org.hibernate.persister.entity.EntityPersister;
/**
@@ -35,25 +37,25 @@ import org.hibernate.persister.entity.EntityPersister;
*
* @author Emmanuel Bernard
*/
-public class JpaDeleteEventListener extends DefaultDeleteEventListener implements CallbackHandlerConsumer {
- private EntityCallbackHandler callbackHandler;
+public class JpaDeleteEventListener extends DefaultDeleteEventListener implements CallbackRegistryConsumer {
+ private CallbackRegistry callbackRegistry;
- public void setCallbackHandler(EntityCallbackHandler callbackHandler) {
- this.callbackHandler = callbackHandler;
+ public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
+ this.callbackRegistry = callbackRegistry;
}
public JpaDeleteEventListener() {
super();
}
- public JpaDeleteEventListener(EntityCallbackHandler callbackHandler) {
+ public JpaDeleteEventListener(CallbackRegistry callbackRegistry) {
this();
- this.callbackHandler = callbackHandler;
+ this.callbackRegistry = callbackRegistry;
}
@Override
protected boolean invokeDeleteLifecycle(EventSource session, Object entity, EntityPersister persister) {
- callbackHandler.preRemove( entity );
+ callbackRegistry.preRemove( entity );
return super.invokeDeleteLifecycle( session, entity, persister );
}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaFlushEntityEventListener.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaFlushEntityEventListener.java
similarity index 82%
rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaFlushEntityEventListener.java
rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaFlushEntityEventListener.java
index e7f162684e..386ae9e193 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaFlushEntityEventListener.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaFlushEntityEventListener.java
@@ -21,13 +21,15 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.jpa.internal.event;
+package org.hibernate.jpa.internal.event.core;
import org.hibernate.SessionFactory;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.Status;
import org.hibernate.event.internal.DefaultFlushEntityEventListener;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistryConsumer;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistry;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.Type;
@@ -37,20 +39,20 @@ import org.hibernate.type.Type;
*
* @author Emmanuel Bernard
*/
-public class JpaFlushEntityEventListener extends DefaultFlushEntityEventListener implements CallbackHandlerConsumer {
- private EntityCallbackHandler callbackHandler;
+public class JpaFlushEntityEventListener extends DefaultFlushEntityEventListener implements CallbackRegistryConsumer {
+ private CallbackRegistry callbackRegistry;
- public void setCallbackHandler(EntityCallbackHandler callbackHandler) {
- this.callbackHandler = callbackHandler;
+ public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
+ this.callbackRegistry = callbackRegistry;
}
public JpaFlushEntityEventListener() {
super();
}
- public JpaFlushEntityEventListener(EntityCallbackHandler callbackHandler) {
+ public JpaFlushEntityEventListener(CallbackRegistry callbackRegistry) {
super();
- this.callbackHandler = callbackHandler;
+ this.callbackRegistry = callbackRegistry;
}
@Override
@@ -62,7 +64,7 @@ public class JpaFlushEntityEventListener extends DefaultFlushEntityEventListener
EntityPersister persister) {
boolean isDirty = false;
if ( entry.getStatus() != Status.DELETED ) {
- if ( callbackHandler.preUpdate( entity ) ) {
+ if ( callbackRegistry.preUpdate( entity ) ) {
isDirty = copyState( entity, persister.getPropertyTypes(), values, session.getFactory() );
}
}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaFlushEventListener.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaFlushEventListener.java
similarity index 97%
rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaFlushEventListener.java
rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaFlushEventListener.java
index 4ebcdb5d35..b37dfd310d 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaFlushEventListener.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaFlushEventListener.java
@@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.jpa.internal.event;
+package org.hibernate.jpa.internal.event.core;
import java.util.IdentityHashMap;
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaMergeEventListener.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaMergeEventListener.java
similarity index 77%
rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaMergeEventListener.java
rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaMergeEventListener.java
index ec7bea6bcd..6d3b847f3f 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaMergeEventListener.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaMergeEventListener.java
@@ -21,32 +21,34 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.jpa.internal.event;
+package org.hibernate.jpa.internal.event.core;
import java.io.Serializable;
import org.hibernate.event.internal.DefaultMergeEventListener;
import org.hibernate.event.spi.EventSource;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistryConsumer;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistry;
/**
* Overrides the LifeCycle OnSave call to call the PrePersist operation
*
* @author Emmanuel Bernard
*/
-public class JpaMergeEventListener extends DefaultMergeEventListener implements CallbackHandlerConsumer {
- private EntityCallbackHandler callbackHandler;
+public class JpaMergeEventListener extends DefaultMergeEventListener implements CallbackRegistryConsumer {
+ private CallbackRegistry callbackRegistry;
- public void setCallbackHandler(EntityCallbackHandler callbackHandler) {
- this.callbackHandler = callbackHandler;
+ public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
+ this.callbackRegistry = callbackRegistry;
}
public JpaMergeEventListener() {
super();
}
- public JpaMergeEventListener(EntityCallbackHandler callbackHandler) {
+ public JpaMergeEventListener(CallbackRegistry callbackRegistry) {
super();
- this.callbackHandler = callbackHandler;
+ this.callbackRegistry = callbackRegistry;
}
@Override
@@ -56,7 +58,7 @@ public class JpaMergeEventListener extends DefaultMergeEventListener implements
String entityName,
Object anything,
EventSource source) {
- callbackHandler.preCreate( entity );
+ callbackRegistry.preCreate( entity );
return super.saveWithRequestedId( entity, requestedId, entityName, anything, source );
}
@@ -67,7 +69,7 @@ public class JpaMergeEventListener extends DefaultMergeEventListener implements
Object anything,
EventSource source,
boolean requiresImmediateIdAccess) {
- callbackHandler.preCreate( entity );
+ callbackRegistry.preCreate( entity );
return super.saveWithGeneratedId( entity, entityName, anything, source, requiresImmediateIdAccess );
}
}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaPersistEventListener.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaPersistEventListener.java
similarity index 85%
rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaPersistEventListener.java
rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaPersistEventListener.java
index ccb6235a99..1949c98e0e 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaPersistEventListener.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaPersistEventListener.java
@@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.jpa.internal.event;
+package org.hibernate.jpa.internal.event.core;
import java.io.Serializable;
import java.util.Iterator;
@@ -34,6 +34,8 @@ import org.hibernate.engine.spi.CascadingAction;
import org.hibernate.engine.spi.CascadingActions;
import org.hibernate.event.internal.DefaultPersistEventListener;
import org.hibernate.event.spi.EventSource;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistryConsumer;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistry;
import org.hibernate.type.CollectionType;
/**
@@ -41,23 +43,23 @@ import org.hibernate.type.CollectionType;
*
* @author Emmanuel Bernard
*/
-public class JpaPersistEventListener extends DefaultPersistEventListener implements CallbackHandlerConsumer {
+public class JpaPersistEventListener extends DefaultPersistEventListener implements CallbackRegistryConsumer {
private static final Logger log = Logger.getLogger( JpaPersistEventListener.class );
- private EntityCallbackHandler callbackHandler;
+ private CallbackRegistry callbackRegistry;
@Override
- public void setCallbackHandler(EntityCallbackHandler callbackHandler) {
- this.callbackHandler = callbackHandler;
+ public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
+ this.callbackRegistry = callbackRegistry;
}
public JpaPersistEventListener() {
super();
}
- public JpaPersistEventListener(EntityCallbackHandler callbackHandler) {
+ public JpaPersistEventListener(CallbackRegistry callbackRegistry) {
super();
- this.callbackHandler = callbackHandler;
+ this.callbackRegistry = callbackRegistry;
}
@Override
@@ -67,7 +69,7 @@ public class JpaPersistEventListener extends DefaultPersistEventListener impleme
String entityName,
Object anything,
EventSource source) {
- callbackHandler.preCreate( entity );
+ callbackRegistry.preCreate( entity );
return super.saveWithRequestedId( entity, requestedId, entityName, anything, source );
}
@@ -78,7 +80,7 @@ public class JpaPersistEventListener extends DefaultPersistEventListener impleme
Object anything,
EventSource source,
boolean requiresImmediateIdAccess) {
- callbackHandler.preCreate( entity );
+ callbackRegistry.preCreate( entity );
return super.saveWithGeneratedId( entity, entityName, anything, source, requiresImmediateIdAccess );
}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaPersistOnFlushEventListener.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaPersistOnFlushEventListener.java
similarity index 96%
rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaPersistOnFlushEventListener.java
rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaPersistOnFlushEventListener.java
index 132c4aedb9..f99ee068d1 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaPersistOnFlushEventListener.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaPersistOnFlushEventListener.java
@@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.jpa.internal.event;
+package org.hibernate.jpa.internal.event.core;
import org.hibernate.engine.spi.CascadingAction;
import org.hibernate.engine.spi.CascadingActions;
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaPostDeleteEventListener.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaPostDeleteEventListener.java
similarity index 73%
rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaPostDeleteEventListener.java
rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaPostDeleteEventListener.java
index b5e13fd965..0309f9b8dc 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaPostDeleteEventListener.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaPostDeleteEventListener.java
@@ -21,32 +21,34 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.jpa.internal.event;
+package org.hibernate.jpa.internal.event.core;
import org.hibernate.event.spi.PostDeleteEvent;
import org.hibernate.event.spi.PostDeleteEventListener;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistryConsumer;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistry;
/**
* @author Kabir Khan
*/
-public class JpaPostDeleteEventListener implements PostDeleteEventListener, CallbackHandlerConsumer {
- EntityCallbackHandler callbackHandler;
+public class JpaPostDeleteEventListener implements PostDeleteEventListener, CallbackRegistryConsumer {
+ CallbackRegistry callbackRegistry;
- public void setCallbackHandler(EntityCallbackHandler callbackHandler) {
- this.callbackHandler = callbackHandler;
+ public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
+ this.callbackRegistry = callbackRegistry;
}
public JpaPostDeleteEventListener() {
super();
}
- public JpaPostDeleteEventListener(EntityCallbackHandler callbackHandler) {
- this.callbackHandler = callbackHandler;
+ public JpaPostDeleteEventListener(CallbackRegistry callbackRegistry) {
+ this.callbackRegistry = callbackRegistry;
}
public void onPostDelete(PostDeleteEvent event) {
Object entity = event.getEntity();
- callbackHandler.postRemove( entity );
+ callbackRegistry.postRemove( entity );
}
}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaPostInsertEventListener.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaPostInsertEventListener.java
similarity index 73%
rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaPostInsertEventListener.java
rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaPostInsertEventListener.java
index 8aa7ad373c..f6b054247c 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaPostInsertEventListener.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaPostInsertEventListener.java
@@ -21,33 +21,35 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.jpa.internal.event;
+package org.hibernate.jpa.internal.event.core;
import org.hibernate.event.spi.PostInsertEvent;
import org.hibernate.event.spi.PostInsertEventListener;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistryConsumer;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistry;
/**
* @author Kabir Khan
*/
-public class JpaPostInsertEventListener implements PostInsertEventListener, CallbackHandlerConsumer {
- EntityCallbackHandler callbackHandler;
+public class JpaPostInsertEventListener implements PostInsertEventListener, CallbackRegistryConsumer {
+ CallbackRegistry callbackRegistry;
@Override
- public void setCallbackHandler(EntityCallbackHandler callbackHandler) {
- this.callbackHandler = callbackHandler;
+ public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
+ this.callbackRegistry = callbackRegistry;
}
public JpaPostInsertEventListener() {
super();
}
- public JpaPostInsertEventListener(EntityCallbackHandler callbackHandler) {
- this.callbackHandler = callbackHandler;
+ public JpaPostInsertEventListener(CallbackRegistry callbackRegistry) {
+ this.callbackRegistry = callbackRegistry;
}
@Override
public void onPostInsert(PostInsertEvent event) {
Object entity = event.getEntity();
- callbackHandler.postCreate( entity );
+ callbackRegistry.postCreate( entity );
}
}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaPostLoadEventListener.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaPostLoadEventListener.java
similarity index 73%
rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaPostLoadEventListener.java
rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaPostLoadEventListener.java
index 6f10739b80..06fc1fb181 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaPostLoadEventListener.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaPostLoadEventListener.java
@@ -21,34 +21,36 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.jpa.internal.event;
+package org.hibernate.jpa.internal.event.core;
import org.hibernate.event.spi.PostLoadEvent;
import org.hibernate.event.spi.PostLoadEventListener;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistryConsumer;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistry;
/**
* @author Kabir Khan
*/
-public class JpaPostLoadEventListener implements PostLoadEventListener, CallbackHandlerConsumer {
- EntityCallbackHandler callbackHandler;
+public class JpaPostLoadEventListener implements PostLoadEventListener, CallbackRegistryConsumer {
+ CallbackRegistry callbackRegistry;
@Override
- public void setCallbackHandler(EntityCallbackHandler callbackHandler) {
- this.callbackHandler = callbackHandler;
+ public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
+ this.callbackRegistry = callbackRegistry;
}
public JpaPostLoadEventListener() {
super();
}
- public JpaPostLoadEventListener(EntityCallbackHandler callbackHandler) {
- this.callbackHandler = callbackHandler;
+ public JpaPostLoadEventListener(CallbackRegistry callbackRegistry) {
+ this.callbackRegistry = callbackRegistry;
}
@Override
public void onPostLoad(PostLoadEvent event) {
Object entity = event.getEntity();
- callbackHandler.postLoad( entity );
+ callbackRegistry.postLoad( entity );
}
}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaPostUpdateEventListener.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaPostUpdateEventListener.java
similarity index 86%
rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaPostUpdateEventListener.java
rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaPostUpdateEventListener.java
index 83d88675c7..54e0befc61 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaPostUpdateEventListener.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaPostUpdateEventListener.java
@@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.jpa.internal.event;
+package org.hibernate.jpa.internal.event.core;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.Status;
@@ -34,6 +34,8 @@ import org.hibernate.event.spi.PostCollectionUpdateEvent;
import org.hibernate.event.spi.PostCollectionUpdateEventListener;
import org.hibernate.event.spi.PostUpdateEvent;
import org.hibernate.event.spi.PostUpdateEventListener;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistryConsumer;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistry;
/**
* Implementation of the post update listeners.
@@ -43,23 +45,23 @@ import org.hibernate.event.spi.PostUpdateEventListener;
@SuppressWarnings("serial")
public class JpaPostUpdateEventListener
implements PostUpdateEventListener,
- CallbackHandlerConsumer,
+ CallbackRegistryConsumer,
PostCollectionRecreateEventListener,
PostCollectionRemoveEventListener,
PostCollectionUpdateEventListener {
- EntityCallbackHandler callbackHandler;
+ CallbackRegistry callbackRegistry;
@Override
- public void setCallbackHandler(EntityCallbackHandler callbackHandler) {
- this.callbackHandler = callbackHandler;
+ public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
+ this.callbackRegistry = callbackRegistry;
}
public JpaPostUpdateEventListener() {
super();
}
- public JpaPostUpdateEventListener(EntityCallbackHandler callbackHandler) {
- this.callbackHandler = callbackHandler;
+ public JpaPostUpdateEventListener(CallbackRegistry callbackRegistry) {
+ this.callbackRegistry = callbackRegistry;
}
@Override
@@ -74,7 +76,7 @@ public class JpaPostUpdateEventListener
.getEntityEntries().get(entity);
// mimic the preUpdate filter
if ( Status.DELETED != entry.getStatus()) {
- callbackHandler.postUpdate(entity);
+ callbackRegistry.postUpdate(entity);
}
}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaSaveEventListener.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaSaveEventListener.java
similarity index 77%
rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaSaveEventListener.java
rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaSaveEventListener.java
index 8f9c7b145c..a0c3e832c9 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaSaveEventListener.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaSaveEventListener.java
@@ -21,32 +21,34 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.jpa.internal.event;
+package org.hibernate.jpa.internal.event.core;
import java.io.Serializable;
import org.hibernate.event.internal.DefaultSaveEventListener;
import org.hibernate.event.spi.EventSource;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistryConsumer;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistry;
/**
* Overrides the LifeCycle OnSave call to call the PrePersist operation
*
* @author Emmanuel Bernard
*/
-public class JpaSaveEventListener extends DefaultSaveEventListener implements CallbackHandlerConsumer {
- private EntityCallbackHandler callbackHandler;
+public class JpaSaveEventListener extends DefaultSaveEventListener implements CallbackRegistryConsumer {
+ private CallbackRegistry callbackRegistry;
- public void setCallbackHandler(EntityCallbackHandler callbackHandler) {
- this.callbackHandler = callbackHandler;
+ public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
+ this.callbackRegistry = callbackRegistry;
}
public JpaSaveEventListener() {
super();
}
- public JpaSaveEventListener(EntityCallbackHandler callbackHandler) {
+ public JpaSaveEventListener(CallbackRegistry callbackRegistry) {
super();
- this.callbackHandler = callbackHandler;
+ this.callbackRegistry = callbackRegistry;
}
@Override
@@ -56,7 +58,7 @@ public class JpaSaveEventListener extends DefaultSaveEventListener implements Ca
String entityName,
Object anything,
EventSource source) {
- callbackHandler.preCreate( entity );
+ callbackRegistry.preCreate( entity );
return super.saveWithRequestedId( entity, requestedId, entityName, anything, source );
}
@@ -67,7 +69,7 @@ public class JpaSaveEventListener extends DefaultSaveEventListener implements Ca
Object anything,
EventSource source,
boolean requiresImmediateIdAccess) {
- callbackHandler.preCreate( entity );
+ callbackRegistry.preCreate( entity );
return super.saveWithGeneratedId( entity, entityName, anything, source, requiresImmediateIdAccess );
}
}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaSaveOrUpdateEventListener.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaSaveOrUpdateEventListener.java
similarity index 77%
rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaSaveOrUpdateEventListener.java
rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaSaveOrUpdateEventListener.java
index 6675764c4c..108c930f91 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/JpaSaveOrUpdateEventListener.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/JpaSaveOrUpdateEventListener.java
@@ -21,32 +21,34 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.jpa.internal.event;
+package org.hibernate.jpa.internal.event.core;
import java.io.Serializable;
import org.hibernate.event.internal.DefaultSaveOrUpdateEventListener;
import org.hibernate.event.spi.EventSource;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistryConsumer;
+import org.hibernate.jpa.internal.event.jpa.CallbackRegistry;
/**
* Overrides the LifeCycle OnSave call to call the PrePersist operation
*
* @author Emmanuel Bernard
*/
-public class JpaSaveOrUpdateEventListener extends DefaultSaveOrUpdateEventListener implements CallbackHandlerConsumer {
- private EntityCallbackHandler callbackHandler;
+public class JpaSaveOrUpdateEventListener extends DefaultSaveOrUpdateEventListener implements CallbackRegistryConsumer {
+ private CallbackRegistry callbackRegistry;
- public void setCallbackHandler(EntityCallbackHandler callbackHandler) {
- this.callbackHandler = callbackHandler;
+ public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
+ this.callbackRegistry = callbackRegistry;
}
public JpaSaveOrUpdateEventListener() {
super();
}
- public JpaSaveOrUpdateEventListener(EntityCallbackHandler callbackHandler) {
+ public JpaSaveOrUpdateEventListener(CallbackRegistry callbackRegistry) {
super();
- this.callbackHandler = callbackHandler;
+ this.callbackRegistry = callbackRegistry;
}
@Override
@@ -56,7 +58,7 @@ public class JpaSaveOrUpdateEventListener extends DefaultSaveOrUpdateEventListen
String entityName,
Object anything,
EventSource source) {
- callbackHandler.preCreate( entity );
+ callbackRegistry.preCreate( entity );
return super.saveWithRequestedId( entity, requestedId, entityName, anything, source );
}
@@ -67,7 +69,7 @@ public class JpaSaveOrUpdateEventListener extends DefaultSaveOrUpdateEventListen
Object anything,
EventSource source,
boolean requiresImmediateIdAccess) {
- callbackHandler.preCreate( entity );
+ callbackRegistry.preCreate( entity );
return super.saveWithGeneratedId( entity, entityName, anything, source, requiresImmediateIdAccess );
}
}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/package-info.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/package-info.java
new file mode 100644
index 0000000000..e7f13fdad3
--- /dev/null
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/core/package-info.java
@@ -0,0 +1,32 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2012, 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.jpa.internal.event.core;
+
+/**
+ * Hibernate EntityManager specific implementations of Hibernate event listeners. Generally the listeners
+ * here either:
+ * - provide tweaks to internal processing to conform with JPA spec
+ * - bridge to JPA event callbacks
+ *
+ */
\ No newline at end of file
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/BeanManagerListenerFactory.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/BeanManagerListenerFactory.java
new file mode 100644
index 0000000000..f9e2724214
--- /dev/null
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/BeanManagerListenerFactory.java
@@ -0,0 +1,87 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2012, 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.jpa.internal.event.jpa;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionTarget;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * CID-based implementation of the ListenerFactory contract. Listener instances are kept in a map keyed by Class
+ * to achieve singleton-ness.
+ *
+ * @author Steve Ebersole
+ */
+public class BeanManagerListenerFactory implements ListenerFactory {
+ private final BeanManager beanManager;
+ private final Map listeners = new ConcurrentHashMap();
+
+ public BeanManagerListenerFactory(BeanManager beanManager) {
+ this.beanManager = beanManager;
+ }
+
+ @Override
+ public T buildListener(Class listenerClass) {
+ BeanMetaData beanMetaData = listeners.get( listenerClass );
+ if ( beanMetaData == null ) {
+ beanMetaData = new BeanMetaData( listenerClass );
+ listeners.put( listenerClass, beanMetaData );
+ }
+ return beanMetaData.instance;
+ }
+
+ @Override
+ public void release() {
+ for ( BeanMetaData beanMetaData : listeners.values() ) {
+ beanMetaData.release();
+ }
+ listeners.clear();
+ }
+
+ private class BeanMetaData {
+ private final InjectionTarget injectionTarget;
+ private final CreationalContext creationalContext;
+ private final T instance;
+
+ private BeanMetaData(Class listenerClass) {
+ AnnotatedType annotatedType = beanManager.createAnnotatedType( listenerClass );
+ this.injectionTarget = beanManager.createInjectionTarget( annotatedType );
+ this.creationalContext = beanManager.createCreationalContext( null );
+
+ this.instance = injectionTarget.produce( creationalContext );
+ injectionTarget.inject( this.instance, creationalContext );
+
+ injectionTarget.postConstruct( this.instance );
+ }
+
+ private void release() {
+ injectionTarget.preDestroy( instance );
+ injectionTarget.dispose( instance );
+ creationalContext.release();
+ }
+ }
+}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/Callback.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/Callback.java
new file mode 100644
index 0000000000..f7520a42bc
--- /dev/null
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/Callback.java
@@ -0,0 +1,41 @@
+/*
+ * 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.jpa.internal.event.jpa;
+
+import java.io.Serializable;
+
+/**
+ * Represents a JPA event callback.
+ *
+ * @author Kabir Khan
+ * @author Steve Ebersole
+ */
+public interface Callback extends Serializable {
+ /**
+ * Contract for performing the callback
+ *
+ * @param entity Reference to the entity for which the callback is triggered.
+ */
+ public abstract void performCallback(Object entity);
+}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/CallbackProcessor.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/CallbackProcessor.java
new file mode 100644
index 0000000000..ef01fefbc5
--- /dev/null
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/CallbackProcessor.java
@@ -0,0 +1,58 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2012, 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.jpa.internal.event.jpa;
+
+import javax.persistence.PostLoad;
+import javax.persistence.PostPersist;
+import javax.persistence.PostRemove;
+import javax.persistence.PostUpdate;
+import javax.persistence.PrePersist;
+import javax.persistence.PreRemove;
+import javax.persistence.PreUpdate;
+
+/**
+ * Delegate for interpreting, parsing and processing callbacks
+ *
+ * @author Steve Ebersole
+ */
+public interface CallbackProcessor {
+ public static final Class[] CALLBACK_ANNOTATION_CLASSES = new Class[] {
+ PreUpdate.class, PostUpdate.class,
+ PrePersist.class, PostPersist.class,
+ PreRemove.class, PostRemove.class,
+ PostLoad.class
+ };
+
+ /**
+ * Ugh, Object to account for Configuration/Metamodel split. Should eventually be EntityBinding from
+ * metamodel code base. Currently each Integrator method passes in different type and each impl
+ * interprets differently.
+ *
+ * @param entityObject
+ * @param registry
+ */
+ public void processCallbacksForEntity(Object entityObject, CallbackRegistry registry);
+
+ public void release();
+}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/CallbackProcessorImpl.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/CallbackProcessorImpl.java
new file mode 100644
index 0000000000..0f69e5ed46
--- /dev/null
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/CallbackProcessorImpl.java
@@ -0,0 +1,162 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2012, 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.jpa.internal.event.jpa;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.logging.Logger;
+
+import org.hibernate.MappingException;
+import org.hibernate.metamodel.binding.EntityBinding;
+import org.hibernate.metamodel.source.MetadataImplementor;
+import org.hibernate.metamodel.source.binder.JpaCallbackClass;
+import org.hibernate.service.classloading.spi.ClassLoaderService;
+import org.hibernate.service.classloading.spi.ClassLoadingException;
+import org.hibernate.service.spi.SessionFactoryServiceRegistry;
+
+/**
+ * @author Steve Ebersole
+ */
+public class CallbackProcessorImpl implements CallbackProcessor {
+ private static final Logger log = Logger.getLogger( CallbackProcessorImpl.class );
+
+ private final ListenerFactory jpaListenerFactory;
+ private final MetadataImplementor metadata;
+
+ private final ClassLoaderService classLoaderService;
+
+ public CallbackProcessorImpl(
+ ListenerFactory jpaListenerFactory,
+ MetadataImplementor metadata,
+ SessionFactoryServiceRegistry serviceRegistry) {
+ this.jpaListenerFactory = jpaListenerFactory;
+ this.metadata = metadata;
+ this.classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
+ }
+
+ @Override
+ public void processCallbacksForEntity(Object entityObject, CallbackRegistry callbackRegistry) {
+ final EntityBinding entityBinding = (EntityBinding) entityObject;
+ final String entityClassName = entityBinding.getEntity().getClassName();
+ if ( entityClassName == null ) {
+ return;
+ }
+
+ try {
+ final Class entityClass = classLoaderService.classForName( entityClassName );
+ for ( Class annotationClass : CALLBACK_ANNOTATION_CLASSES ) {
+ callbackRegistry.addEntityCallbacks(
+ entityClass,
+ annotationClass,
+ collectCallbacks( entityBinding, entityClass, annotationClass )
+ );
+ }
+ }
+ catch (ClassLoadingException e) {
+ throw new MappingException( "entity class not found: " + entityClassName, e );
+ }
+ }
+
+ private Callback[] collectCallbacks(EntityBinding entityBinding, Class entityClass, Class annotationClass) {
+ final List callbacks = new ArrayList();
+ for ( JpaCallbackClass jpaCallbackClass : entityBinding.getJpaCallbackClasses() ) {
+ final Class listenerClass = classLoaderService.classForName( jpaCallbackClass.getName() );
+ final String methodName = jpaCallbackClass.getCallbackMethod( annotationClass );
+
+ log.debugf(
+ "Adding $s.%s as %s callback for entity %s",
+ listenerClass.getName(),
+ methodName,
+ annotationClass.getName(),
+ entityClass.getName()
+ );
+
+ final Callback callback = jpaCallbackClass.isListener()
+ ? createListenerCallback( listenerClass, entityClass, methodName )
+ : createBeanCallback( listenerClass, methodName );
+ assert callback != null;
+ callbacks.add(callback);
+ }
+ return callbacks.toArray(new Callback[callbacks.size()]);
+ }
+
+ private Callback createListenerCallback(
+ Class listenerClass,
+ Class entityClass,
+ String methodName ) {
+ final Class> callbackSuperclass = listenerClass.getSuperclass();
+ if ( callbackSuperclass != null ) {
+ Callback callback = createListenerCallback( entityClass, callbackSuperclass, methodName );
+ if ( callback != null ) {
+ return callback;
+ }
+ }
+
+ final Object listenerInstance = jpaListenerFactory.buildListener( listenerClass );
+ for ( Method method : listenerClass.getDeclaredMethods() ) {
+ if ( !method.getName().equals(methodName) ) {
+ continue;
+ }
+
+ final Class>[] argTypes = method.getParameterTypes();
+ if (argTypes.length != 1) {
+ continue;
+ }
+
+ final Class> argType = argTypes[0];
+ if (argType != Object.class && argType != entityClass) {
+ continue;
+ }
+ if (!method.isAccessible()) {
+ method.setAccessible( true );
+ }
+
+ return new ListenerCallback( listenerInstance, method );
+ }
+ return null;
+ }
+
+ private Callback createBeanCallback( Class> callbackClass,
+ String methodName ) {
+ Class> callbackSuperclass = callbackClass.getSuperclass();
+ if (callbackSuperclass != null) {
+ Callback callback = createBeanCallback(callbackSuperclass, methodName);
+ if (callback != null) return callback;
+ }
+ for (Method method : callbackClass.getDeclaredMethods()) {
+ if (!method.getName().equals(methodName)) continue;
+ if (method.getParameterTypes().length != 0) continue;
+ if (!method.isAccessible()) method.setAccessible(true);
+ return new EntityCallback(method);
+ }
+ return null;
+ }
+
+ @Override
+ public void release() {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/EntityCallbackHandler.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/CallbackRegistry.java
similarity index 56%
rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/EntityCallbackHandler.java
rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/CallbackRegistry.java
index 8b5c42b681..77e0a442f8 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/EntityCallbackHandler.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/CallbackRegistry.java
@@ -21,10 +21,9 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.jpa.internal.event;
+package org.hibernate.jpa.internal.event.jpa;
-import java.io.Serializable;
-import java.util.HashMap;
+import javax.persistence.PersistenceException;
import javax.persistence.PostLoad;
import javax.persistence.PostPersist;
import javax.persistence.PostRemove;
@@ -32,19 +31,17 @@ import javax.persistence.PostUpdate;
import javax.persistence.PrePersist;
import javax.persistence.PreRemove;
import javax.persistence.PreUpdate;
-
-import org.hibernate.annotations.common.reflection.ReflectionManager;
-import org.hibernate.annotations.common.reflection.XClass;
-import org.hibernate.metamodel.binding.EntityBinding;
-import org.hibernate.service.classloading.spi.ClassLoaderService;
+import java.io.Serializable;
+import java.util.HashMap;
/**
* Keep track of all lifecycle callbacks and listeners for a given persistence unit
*
* @author Kabir Khan
+ * @author Steve Ebersole
*/
@SuppressWarnings({"unchecked", "serial"})
-public class EntityCallbackHandler implements Serializable {
+public class CallbackRegistry implements Serializable {
private HashMap preCreates = new HashMap();
private HashMap postCreates = new HashMap();
private HashMap preRemoves = new HashMap();
@@ -53,28 +50,6 @@ public class EntityCallbackHandler implements Serializable {
private HashMap postUpdates = new HashMap();
private HashMap postLoads = new HashMap();
- public void add(XClass entity, ReflectionManager reflectionManager) {
- addCallback( entity, preCreates, PrePersist.class, reflectionManager );
- addCallback( entity, postCreates, PostPersist.class, reflectionManager );
- addCallback( entity, preRemoves, PreRemove.class, reflectionManager );
- addCallback( entity, postRemoves, PostRemove.class, reflectionManager );
- addCallback( entity, preUpdates, PreUpdate.class, reflectionManager );
- addCallback( entity, postUpdates, PostUpdate.class, reflectionManager );
- addCallback( entity, postLoads, PostLoad.class, reflectionManager );
- }
-
- public void add( Class entity,
- ClassLoaderService classLoaderService,
- EntityBinding binding ) {
- addCallback( entity, preCreates, PrePersist.class, classLoaderService, binding );
- addCallback( entity, postCreates, PostPersist.class, classLoaderService, binding );
- addCallback( entity, preRemoves, PreRemove.class, classLoaderService, binding );
- addCallback( entity, postRemoves, PostRemove.class, classLoaderService, binding );
- addCallback( entity, preUpdates, PreUpdate.class, classLoaderService, binding );
- addCallback( entity, postUpdates, PostUpdate.class, classLoaderService, binding );
- addCallback( entity, postLoads, PostLoad.class, classLoaderService, binding );
- }
-
public boolean preCreate(Object bean) {
return callback( preCreates.get( bean.getClass() ), bean );
}
@@ -103,11 +78,10 @@ public class EntityCallbackHandler implements Serializable {
return callback( postLoads.get( bean.getClass() ), bean );
}
-
private boolean callback(Callback[] callbacks, Object bean) {
if ( callbacks != null && callbacks.length != 0 ) {
for ( Callback callback : callbacks ) {
- callback.invoke( bean );
+ callback.performCallback( bean );
}
return true;
}
@@ -116,19 +90,56 @@ public class EntityCallbackHandler implements Serializable {
}
}
- private void addCallback(
- XClass entity, HashMap map, Class annotation, ReflectionManager reflectionManager
- ) {
- Callback[] callbacks = null;
- callbacks = CallbackResolver.resolveCallback( entity, annotation, reflectionManager );
- map.put( reflectionManager.toClass( entity ), callbacks );
+ /* package */ void addEntityCallbacks(Class entityClass, Class annotationClass, Callback[] callbacks) {
+ final HashMap map = determineAppropriateCallbackMap( annotationClass );
+ if ( map.containsKey( entityClass ) ) {
+ throw new PersistenceException( "Error build callback listeners; entity [" + entityClass.getName() + " was already processed" );
+ }
+ map.put( entityClass, callbacks );
}
- private void addCallback( Class> entity,
- HashMap map,
- Class annotation,
- ClassLoaderService classLoaderService,
- EntityBinding binding ) {
- map.put(entity, CallbackResolver.resolveCallbacks(entity, annotation, classLoaderService, binding));
- }
+ private HashMap determineAppropriateCallbackMap(Class annotationClass) {
+ if ( PrePersist.class.equals( annotationClass ) ) {
+ return preCreates;
+ }
+
+ if ( PostPersist.class.equals( annotationClass ) ) {
+ return postCreates;
+ }
+
+ if ( PreRemove.class.equals( annotationClass ) ) {
+ return preRemoves;
+ }
+
+ if ( PostRemove.class.equals( annotationClass ) ) {
+ return postRemoves;
+ }
+
+ if ( PreUpdate.class.equals( annotationClass ) ) {
+ return preUpdates;
+ }
+
+ if ( PostUpdate.class.equals( annotationClass ) ) {
+ return postUpdates;
+ }
+
+ if ( PostLoad.class.equals( annotationClass ) ) {
+ return postLoads;
+ }
+
+ throw new PersistenceException( "Unrecognized JPA callback annotation [" + annotationClass.getName() + "]" );
+ }
+
+ public void release() {
+ preCreates.clear();
+ postCreates.clear();
+
+ preRemoves.clear();
+ postRemoves.clear();
+
+ preUpdates.clear();
+ postUpdates.clear();
+
+ postLoads.clear();
+ }
}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/CallbackRegistryConsumer.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/CallbackRegistryConsumer.java
new file mode 100644
index 0000000000..4175ee85ae
--- /dev/null
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/CallbackRegistryConsumer.java
@@ -0,0 +1,41 @@
+/*
+ * 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.jpa.internal.event.jpa;
+
+import org.hibernate.jpa.internal.event.core.HibernateEntityManagerEventListener;
+
+/**
+ * Contract for injecting the registry of Callbacks into event listeners.
+ *
+ * @author Emmanuel Bernard
+ * @author Steve Ebersole
+ */
+public interface CallbackRegistryConsumer extends HibernateEntityManagerEventListener {
+ /**
+ * Injection of the CallbackRegistry
+ *
+ * @param callbackRegistry The CallbackRegistry
+ */
+ public void injectCallbackRegistry(CallbackRegistry callbackRegistry);
+}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/BeanCallback.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/EntityCallback.java
similarity index 80%
rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/BeanCallback.java
rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/EntityCallback.java
index 445aadcb37..bbf526a916 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/BeanCallback.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/EntityCallback.java
@@ -21,22 +21,28 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.jpa.internal.event;
+package org.hibernate.jpa.internal.event.jpa;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
+ * Represents a JPA callback on the entity itself
+ *
* @author Kabir Khan
+ * @author Steve Ebersole
*/
-public class BeanCallback extends Callback {
- public BeanCallback(Method callbackMethod) {
- super( callbackMethod );
+public class EntityCallback implements Callback {
+ private Method callbackMethod;
+
+ public EntityCallback(Method callbackMethod) {
+ this.callbackMethod = callbackMethod;
}
- public void invoke(Object bean) {
+ @Override
+ public void performCallback(Object entity) {
try {
- callbackMethod.invoke( bean, new Object[0] );
+ callbackMethod.invoke( entity );
}
catch (InvocationTargetException e) {
//keep runtime exceptions as is
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/CallbackResolver.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/LegacyCallbackProcessor.java
similarity index 58%
rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/CallbackResolver.java
rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/LegacyCallbackProcessor.java
index 28905a1f75..1a4d5cd0dd 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/CallbackResolver.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/LegacyCallbackProcessor.java
@@ -1,7 +1,7 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2009-2011, Red Hat Inc. or third-party contributors as
+ * Copyright (c) 2012, 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.
@@ -21,7 +21,21 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.jpa.internal.event;
+package org.hibernate.jpa.internal.event.jpa;
+
+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 javax.persistence.PostLoad;
+import javax.persistence.PostPersist;
+import javax.persistence.PostRemove;
+import javax.persistence.PostUpdate;
+import javax.persistence.PrePersist;
+import javax.persistence.PreRemove;
+import javax.persistence.PreUpdate;
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
@@ -29,48 +43,46 @@ 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 org.jboss.logging.Logger;
+import org.hibernate.MappingException;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XMethod;
-import org.hibernate.jpa.internal.EntityManagerMessageLogger;
-import org.hibernate.metamodel.binding.EntityBinding;
-import org.hibernate.metamodel.source.binder.JpaCallbackClass;
-import org.hibernate.service.classloading.spi.ClassLoaderService;
/**
* @author Kabir Khan
+ * @author Steve Ebersole
*/
-public final class CallbackResolver {
+public class LegacyCallbackProcessor implements CallbackProcessor {
+ private static final Logger log = Logger.getLogger( LegacyCallbackProcessor.class );
- private static final EntityManagerMessageLogger LOG = Logger.getMessageLogger(EntityManagerMessageLogger.class,
- CallbackResolver.class.getName());
+ private final ListenerFactory jpaListenerFactory;
+ private final ReflectionManager reflectionManager;
- private static boolean useAnnotationAnnotatedByListener;
+ public LegacyCallbackProcessor(ListenerFactory jpaListenerFactory, ReflectionManager reflectionManager) {
+ this.jpaListenerFactory = jpaListenerFactory;
+ this.reflectionManager = reflectionManager;
+ }
- static {
- //check whether reading annotations of annotations is useful or not
- useAnnotationAnnotatedByListener = false;
- Target target = EntityListeners.class.getAnnotation( Target.class );
- if ( target != null ) {
- for ( ElementType type : target.value() ) {
- if ( type.equals( ElementType.ANNOTATION_TYPE ) ) useAnnotationAnnotatedByListener = true;
+ @Override
+ public void processCallbacksForEntity(Object entityObject, CallbackRegistry callbackRegistry) {
+ final String entityClassName = (String) entityObject;
+ try {
+ final XClass entityXClass = reflectionManager.classForName( entityClassName, this.getClass() );
+ final Class entityClass = reflectionManager.toClass( entityXClass );
+ for ( Class annotationClass : CALLBACK_ANNOTATION_CLASSES ) {
+ final Callback[] callbacks = resolveCallbacks( entityXClass, annotationClass, reflectionManager );
+ callbackRegistry.addEntityCallbacks( entityClass, annotationClass, callbacks );
}
}
+ catch (ClassNotFoundException e) {
+ throw new MappingException( "entity class not found: " + entityClassName, e );
+ }
}
- private CallbackResolver() {
- }
-
- public static Callback[] resolveCallback(XClass beanClass, Class annotation, ReflectionManager reflectionManager) {
+ public Callback[] resolveCallbacks(XClass beanClass, Class annotation, ReflectionManager reflectionManager) {
List callbacks = new ArrayList();
List callbacksMethodNames = new ArrayList(); //used to track overridden methods
List orderedListeners = new ArrayList();
@@ -89,7 +101,7 @@ public final class CallbackResolver {
if ( ! callbacksMethodNames.contains( methodName ) ) {
//overridden method, remove the superclass overridden method
if ( callback == null ) {
- callback = new BeanCallback( method );
+ callback = new EntityCallback( method );
Class returnType = method.getReturnType();
Class[] args = method.getParameterTypes();
if ( returnType != Void.TYPE || args.length != 0 ) {
@@ -98,11 +110,11 @@ public final class CallbackResolver {
.getName() + " - " + xMethod
);
}
- if (!method.isAccessible()) method.setAccessible(true);
- LOG.debugf("Adding %s as %s callback for entity %s",
- methodName,
- annotation.getSimpleName(),
- beanClass.getName());
+ if (!method.isAccessible()) method.setAccessible(true);
+ log.debugf("Adding %s as %s callback for entity %s",
+ methodName,
+ annotation.getSimpleName(),
+ beanClass.getName());
callbacks.add( 0, callback ); //superclass first
callbacksMethodNames.add( 0, methodName );
}
@@ -158,21 +170,8 @@ public final class CallbackResolver {
if ( ! callbacksMethodNames.contains( methodName ) ) {
//overridden method, remove the superclass overridden method
if ( callback == null ) {
- try {
- callback = new ListenerCallback( method, listener.newInstance() );
- }
- catch (IllegalAccessException e) {
- throw new PersistenceException(
- "Unable to create instance of " + listener.getName()
- + " as a listener of beanClass", e
- );
- }
- catch (InstantiationException e) {
- throw new PersistenceException(
- "Unable to create instance of " + listener.getName()
- + " as a listener of beanClass", e
- );
- }
+ callback = new ListenerCallback( jpaListenerFactory.buildListener( listener ), method );
+
Class returnType = method.getReturnType();
Class[] args = method.getParameterTypes();
if ( returnType != Void.TYPE || args.length != 1 ) {
@@ -181,11 +180,11 @@ public final class CallbackResolver {
.getName() + " - " + method
);
}
- if (!method.isAccessible()) method.setAccessible(true);
- LOG.debugf("Adding %s as %s callback for entity %s",
- methodName,
- annotation.getSimpleName(),
- beanClass.getName());
+ if (!method.isAccessible()) method.setAccessible(true);
+ log.debugf("Adding %s as %s callback for entity %s",
+ methodName,
+ annotation.getSimpleName(),
+ beanClass.getName());
callbacks.add( 0, callback ); // listeners first
}
else {
@@ -203,61 +202,18 @@ public final class CallbackResolver {
return callbacks.toArray( new Callback[ callbacks.size() ] );
}
- public static Callback[] resolveCallbacks( Class> entityClass,
- Class> callbackClass,
- ClassLoaderService classLoaderService,
- EntityBinding binding ) {
- List callbacks = new ArrayList();
- for (JpaCallbackClass jpaCallbackClass : binding.getJpaCallbackClasses()) {
- Object listener = classLoaderService.classForName(jpaCallbackClass.getName());
- String methodName = jpaCallbackClass.getCallbackMethod( callbackClass );
- Callback callback = jpaCallbackClass.isListener() ?
- createListenerCallback(entityClass, callbackClass, listener, methodName) :
- createBeanCallback(callbackClass, methodName);
- LOG.debugf("Adding %s as %s callback for entity %s", methodName, callbackClass.getName(),
- entityClass.getName());
- assert callback != null;
- callbacks.add(callback);
- }
- return callbacks.toArray(new Callback[callbacks.size()]);
- }
+ private static boolean useAnnotationAnnotatedByListener;
- private static Callback createListenerCallback( Class> entityClass,
- Class> callbackClass,
- Object listener,
- String methodName ) {
- Class> callbackSuperclass = callbackClass.getSuperclass();
- if (callbackSuperclass != null) {
- Callback callback = createListenerCallback(entityClass, callbackSuperclass, listener, methodName);
- if (callback != null) return callback;
- }
- for (Method method : callbackClass.getDeclaredMethods()) {
- if (!method.getName().equals(methodName)) continue;
- Class>[] argTypes = method.getParameterTypes();
- if (argTypes.length != 1) continue;
- Class> argType = argTypes[0];
- if (argType != Object.class && argType != entityClass) continue;
- if (!method.isAccessible()) method.setAccessible(true);
- return new ListenerCallback(method, listener);
- }
- return null;
- }
-
- private static Callback createBeanCallback( Class> callbackClass,
- String methodName ) {
- Class> callbackSuperclass = callbackClass.getSuperclass();
- if (callbackSuperclass != null) {
- Callback callback = createBeanCallback(callbackSuperclass, methodName);
- if (callback != null) return callback;
- }
- for (Method method : callbackClass.getDeclaredMethods()) {
- if (!method.getName().equals(methodName)) continue;
- if (method.getParameterTypes().length != 0) continue;
- if (!method.isAccessible()) method.setAccessible(true);
- return new BeanCallback(method);
- }
- return null;
- }
+ static {
+ //check whether reading annotations of annotations is useful or not
+ useAnnotationAnnotatedByListener = false;
+ Target target = EntityListeners.class.getAnnotation( Target.class );
+ if ( target != null ) {
+ for ( ElementType type : target.value() ) {
+ if ( type.equals( ElementType.ANNOTATION_TYPE ) ) useAnnotationAnnotatedByListener = true;
+ }
+ }
+ }
private static void getListeners(XClass currentClazz, List orderedListeners) {
EntityListeners entityListeners = currentClazz.getAnnotation( EntityListeners.class );
@@ -282,4 +238,9 @@ public final class CallbackResolver {
}
}
}
+
+ @Override
+ public void release() {
+ // nothing to do here
+ }
}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/ListenerCallback.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/ListenerCallback.java
similarity index 57%
rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/ListenerCallback.java
rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/ListenerCallback.java
index 0796d3f269..a0b2414238 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/ListenerCallback.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/ListenerCallback.java
@@ -21,31 +21,30 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.jpa.internal.event;
+package org.hibernate.jpa.internal.event.jpa;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import org.hibernate.internal.util.ReflectHelper;
-
/**
+ * Represents a JPA callback using a dedicated listener
+ *
* @author Kabir Khan
+ * @author Steve Ebersole
*/
-public class ListenerCallback extends Callback {
- protected transient Object listener;
+public class ListenerCallback implements Callback {
+ private final Method callbackMethod;
+ private final Object listenerInstance;
- public ListenerCallback(Method callbackMethod, Object listener) {
- super( callbackMethod );
- this.listener = listener;
+ public ListenerCallback(Object listenerInstance, Method callbackMethod) {
+ this.listenerInstance = listenerInstance;
+ this.callbackMethod = callbackMethod;
}
@Override
- public void invoke(Object bean) {
+ public void performCallback(Object entity) {
try {
- callbackMethod.invoke( listener, new Object[]{bean} );
+ callbackMethod.invoke( listenerInstance, entity );
}
catch (InvocationTargetException e) {
//keep runtime exceptions as is
@@ -60,23 +59,4 @@ public class ListenerCallback extends Callback {
throw new RuntimeException( e );
}
}
-
- private void writeObject(ObjectOutputStream oos) throws IOException {
- oos.defaultWriteObject();
- oos.writeObject( listener.getClass().getName() );
- }
-
- private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
- ois.defaultReadObject();
- String listenerClass = (String) ois.readObject();
- try {
- listener = ReflectHelper.classForName( listenerClass, this.getClass() ).newInstance();
- }
- catch (InstantiationException e) {
- throw new ClassNotFoundException( "Unable to load class:" + listenerClass, e );
- }
- catch (IllegalAccessException e) {
- throw new ClassNotFoundException( "Unable to load class:" + listenerClass, e );
- }
- }
}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/ListenerFactory.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/ListenerFactory.java
new file mode 100644
index 0000000000..f2622a6976
--- /dev/null
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/ListenerFactory.java
@@ -0,0 +1,35 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2012, 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.jpa.internal.event.jpa;
+
+/**
+ * Factory for building instances user-specified event listeners.
+ *
+ * @author Steve Ebersole
+ */
+public interface ListenerFactory {
+ public T buildListener(Class listenerClass);
+
+ public void release();
+}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/StandardListenerFactory.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/StandardListenerFactory.java
new file mode 100644
index 0000000000..c0769adb0e
--- /dev/null
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/StandardListenerFactory.java
@@ -0,0 +1,62 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2012, 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.jpa.internal.event.jpa;
+
+import javax.persistence.PersistenceException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Standard implementation of the ListenerFactory contract using simple instantiation. Listener instances
+ * are kept in a map keyed by Class to achieve singleton-ness.
+ *
+ * @author Steve Ebersole
+ */
+public class StandardListenerFactory implements ListenerFactory {
+ private Map listenerInstances = new ConcurrentHashMap();
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public T buildListener(Class listenerClass) {
+ Object listenerInstance = listenerInstances.get( listenerClass );
+ if ( listenerInstance == null ) {
+ try {
+ listenerInstance = listenerClass.newInstance();
+ }
+ catch (Exception e) {
+ throw new PersistenceException(
+ "Unable to create instance of " + listenerClass.getName() + " as a JPA callback listener",
+ e
+ );
+ }
+ listenerInstances.put( listenerClass, listenerInstance );
+ }
+ return (T) listenerInstance;
+ }
+
+ @Override
+ public void release() {
+ listenerInstances.clear();
+ }
+}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/CallbackHandlerConsumer.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/package-info.java
similarity index 76%
rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/CallbackHandlerConsumer.java
rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/package-info.java
index 420435bea4..69b0bdcf4b 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/CallbackHandlerConsumer.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/event/jpa/package-info.java
@@ -1,7 +1,7 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2009-2011, Red Hat Inc. or third-party contributors as
+ * Copyright (c) 2012, 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.
@@ -21,11 +21,8 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.jpa.internal.event;
+package org.hibernate.jpa.internal.event.jpa;
/**
- * @author Emmanuel Bernard
- */
-public interface CallbackHandlerConsumer extends HibernateEntityManagerEventListener {
- void setCallbackHandler(EntityCallbackHandler callbackHandler);
-}
+ * Classes for integrating with JPA event callbacks
+ */
\ No newline at end of file
diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/BaseEntityManagerFunctionalTestCase.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/BaseEntityManagerFunctionalTestCase.java
index 62d3a0ef60..27df78bada 100644
--- a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/BaseEntityManagerFunctionalTestCase.java
+++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/BaseEntityManagerFunctionalTestCase.java
@@ -40,7 +40,7 @@ import org.jboss.logging.Logger;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.Dialect;
-import org.hibernate.ejb.AvailableSettings;
+import org.hibernate.jpa.AvailableSettings;
import org.hibernate.jpa.internal.EntityManagerFactoryImpl;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.jpa.HibernatePersistenceProvider;
diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/cdi/BaseCDIIntegrationTest.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/cdi/BaseCDIIntegrationTest.java
new file mode 100644
index 0000000000..6d134fe9ce
--- /dev/null
+++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/cdi/BaseCDIIntegrationTest.java
@@ -0,0 +1,66 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2012, 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.jpa.test.cdi;
+
+import javax.enterprise.inject.spi.BeanManager;
+import java.util.Map;
+
+import org.jboss.arquillian.container.weld.ee.embedded_1_1.mock.TestContainer;
+import org.jboss.weld.bootstrap.api.Environments;
+
+import org.hibernate.jpa.AvailableSettings;
+import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
+
+/**
+ * @author Steve Ebersole
+ */
+public abstract class BaseCDIIntegrationTest extends BaseEntityManagerFunctionalTestCase {
+ private TestContainer testContainer;
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected void addConfigOptions(Map options) {
+ super.addConfigOptions( options );
+
+ testContainer = new TestContainer( getCdiBeans() );
+ testContainer.getBootstrap().startContainer( Environments.SE, testContainer.getDeployment() );
+ testContainer.getBootstrap().startInitialization();
+ testContainer.getBootstrap().deployBeans();
+ testContainer.getBootstrap().validateBeans().endInitialization();
+ options.put( AvailableSettings.CDI_BEAN_MANAGER, getBeanManager() );
+ }
+
+ protected BeanManager getBeanManager() {
+ return testContainer.getBeanManager( testContainer.getDeployment().getBeanDeploymentArchives().iterator().next() );
+ }
+
+ public abstract Class[] getCdiBeans();
+
+ @Override
+ public void releaseResources() {
+ super.releaseResources(); // closes the EMF
+
+ testContainer.stopContainer();
+ }
+}
diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/cdi/BasicCDITest.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/cdi/BasicCDITest.java
new file mode 100644
index 0000000000..a755cb2982
--- /dev/null
+++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/cdi/BasicCDITest.java
@@ -0,0 +1,166 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2012, 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.jpa.test.cdi;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.InjectionTarget;
+import javax.inject.Inject;
+import javax.persistence.Entity;
+import javax.persistence.EntityListeners;
+import javax.persistence.EntityManager;
+import javax.persistence.Id;
+import javax.persistence.PrePersist;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Steve Ebersole
+ */
+public class BasicCDITest extends BaseCDIIntegrationTest {
+ private static int count;
+
+ @Override
+ public Class[] getCdiBeans() {
+ return new Class[] { EventQueue.class };
+ }
+
+ @Override
+ protected Class>[] getAnnotatedClasses() {
+ return new Class[] { MyEntity.class };
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testIt() {
+ count = 0;
+
+ EntityManager em = getOrCreateEntityManager();
+ em.getTransaction().begin();
+ em.persist( new MyEntity( 1 ) );
+ em.getTransaction().commit();
+ em.close();
+
+ assertEquals( 1, count );
+
+ em = getOrCreateEntityManager();
+ em.getTransaction().begin();
+ em.remove( em.getReference( MyEntity.class, 1 ) );
+ em.getTransaction().commit();
+ em.close();
+ }
+
+ @Entity
+ @EntityListeners( Monitor.class )
+ public static class MyEntity {
+ private Integer id;
+ private String name;
+
+ public MyEntity() {
+ }
+
+ public MyEntity(Integer id) {
+ this.id = id;
+ }
+
+ @Id
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+ }
+
+ public static class EventQueue {
+ private List events;
+
+ public void addEvent(Event anEvent) {
+ if ( events == null ) {
+ events = new ArrayList();
+ }
+ events.add( anEvent );
+ }
+ }
+
+ public static class Event {
+ private final String who;
+ private final String what;
+ private final String when;
+
+ public Event(String who, String what, String when) {
+ this.who = who;
+ this.what = what;
+ this.when = when;
+ }
+
+ public String getWho() {
+ return who;
+ }
+
+ public String getWhat() {
+ return what;
+ }
+
+ public String getWhen() {
+ return when;
+ }
+ }
+
+ public static class Monitor {
+ private final EventQueue eventQueue;
+
+ @Inject
+ public Monitor(EventQueue eventQueue) {
+ this.eventQueue = eventQueue;
+ }
+
+ @PrePersist
+ public void onCreate(Object entity) {
+ eventQueue.addEvent(
+ new Event( entity.toString(), "created", now() )
+ );
+ count++;
+ }
+
+ private String now() {
+ return new SimpleDateFormat().format( new Date() );
+ }
+ }
+}