HHH-7387 - Integrate Draft 6 of the JPA 2.1 spec : CDI support
This commit is contained in:
parent
d252a141d0
commit
f74cf0b83f
|
@ -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" )
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
|
||||
*/
|
||||
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<Class> parameters = new ArrayList<Class>();
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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).
|
|
@ -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;
|
||||
|
|
@ -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 );
|
||||
}
|
||||
|
|
@ -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() );
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -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 );
|
||||
}
|
||||
|
|
@ -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;
|
|
@ -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 <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
|
||||
*/
|
||||
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 );
|
||||
}
|
||||
|
||||
}
|
|
@ -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 <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
|
||||
*/
|
||||
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 );
|
||||
}
|
||||
}
|
|
@ -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 <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
|
||||
*/
|
||||
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 );
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -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:<ul>
|
||||
* <li>provide tweaks to internal processing to conform with JPA spec</li>
|
||||
* <li>bridge to JPA event callbacks</li>
|
||||
* </ul>
|
||||
*/
|
|
@ -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<Class,BeanMetaData> listeners = new ConcurrentHashMap<Class, BeanMetaData>();
|
||||
|
||||
public BeanManagerListenerFactory(BeanManager beanManager) {
|
||||
this.beanManager = beanManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T buildListener(Class<T> listenerClass) {
|
||||
BeanMetaData<T> beanMetaData = listeners.get( listenerClass );
|
||||
if ( beanMetaData == null ) {
|
||||
beanMetaData = new BeanMetaData<T>( listenerClass );
|
||||
listeners.put( listenerClass, beanMetaData );
|
||||
}
|
||||
return beanMetaData.instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
for ( BeanMetaData beanMetaData : listeners.values() ) {
|
||||
beanMetaData.release();
|
||||
}
|
||||
listeners.clear();
|
||||
}
|
||||
|
||||
private class BeanMetaData<T> {
|
||||
private final InjectionTarget<T> injectionTarget;
|
||||
private final CreationalContext<T> creationalContext;
|
||||
private final T instance;
|
||||
|
||||
private BeanMetaData(Class<T> listenerClass) {
|
||||
AnnotatedType<T> 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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
|
||||
* @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);
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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<Callback> callbacks = new ArrayList<Callback>();
|
||||
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.
|
||||
}
|
||||
}
|
|
@ -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 <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "serial"})
|
||||
public class EntityCallbackHandler implements Serializable {
|
||||
public class CallbackRegistry implements Serializable {
|
||||
private HashMap<Class, Callback[]> preCreates = new HashMap<Class, Callback[]>();
|
||||
private HashMap<Class, Callback[]> postCreates = new HashMap<Class, Callback[]>();
|
||||
private HashMap<Class, Callback[]> preRemoves = new HashMap<Class, Callback[]>();
|
||||
|
@ -53,28 +50,6 @@ public class EntityCallbackHandler implements Serializable {
|
|||
private HashMap<Class, Callback[]> postUpdates = new HashMap<Class, Callback[]>();
|
||||
private HashMap<Class, Callback[]> postLoads = new HashMap<Class, Callback[]>();
|
||||
|
||||
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<Class, Callback[]> 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<Class, Callback[]> 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<Class, Callback[]> map,
|
||||
Class annotation,
|
||||
ClassLoaderService classLoaderService,
|
||||
EntityBinding binding ) {
|
||||
map.put(entity, CallbackResolver.resolveCallbacks(entity, annotation, classLoaderService, binding));
|
||||
}
|
||||
private HashMap<Class, Callback[]> 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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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 <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
|
||||
* @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
|
|
@ -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 <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
|
||||
* @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<Callback> callbacks = new ArrayList<Callback>();
|
||||
List<String> callbacksMethodNames = new ArrayList<String>(); //used to track overridden methods
|
||||
List<Class> orderedListeners = new ArrayList<Class>();
|
||||
|
@ -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<Callback> callbacks = new ArrayList<Callback>();
|
||||
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<Class> orderedListeners) {
|
||||
EntityListeners entityListeners = currentClazz.getAnnotation( EntityListeners.class );
|
||||
|
@ -282,4 +238,9 @@ public final class CallbackResolver {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
// nothing to do here
|
||||
}
|
||||
}
|
|
@ -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 <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
|
||||
* @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 );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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> T buildListener(Class<T> listenerClass);
|
||||
|
||||
public void release();
|
||||
}
|
|
@ -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> T buildListener(Class<T> 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();
|
||||
}
|
||||
}
|
|
@ -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
|
||||
* Classes for integrating with JPA event callbacks
|
||||
*/
|
||||
public interface CallbackHandlerConsumer extends HibernateEntityManagerEventListener {
|
||||
void setCallbackHandler(EntityCallbackHandler callbackHandler);
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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<Event> events;
|
||||
|
||||
public void addEvent(Event anEvent) {
|
||||
if ( events == null ) {
|
||||
events = new ArrayList<Event>();
|
||||
}
|
||||
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() );
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue