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.jpa )
|
||||||
compile( libraries.jta )
|
compile( libraries.jta )
|
||||||
compile( libraries.javassist )
|
compile( libraries.javassist )
|
||||||
|
provided( "javax.enterprise:cdi-api:1.0-SP4" )
|
||||||
testCompile( project(':hibernate-testing') )
|
testCompile( project(':hibernate-testing') )
|
||||||
testCompile( libraries.shrinkwrap_api )
|
testCompile( libraries.shrinkwrap_api )
|
||||||
testCompile( libraries.shrinkwrap )
|
testCompile( libraries.shrinkwrap )
|
||||||
testCompile( libraries.validation )
|
testCompile( libraries.validation )
|
||||||
testRuntime( libraries.validator )
|
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";
|
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
|
// 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;
|
package org.hibernate.jpa.internal.event;
|
||||||
|
|
||||||
|
import javax.enterprise.inject.spi.BeanManager;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.MappingException;
|
|
||||||
import org.hibernate.annotations.common.reflection.ReflectionManager;
|
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.cfg.Configuration;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.engine.spi.CascadeStyles;
|
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.event.spi.EventType;
|
||||||
import org.hibernate.integrator.spi.Integrator;
|
import org.hibernate.integrator.spi.Integrator;
|
||||||
import org.hibernate.jpa.AvailableSettings;
|
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.mapping.PersistentClass;
|
||||||
import org.hibernate.metamodel.binding.EntityBinding;
|
import org.hibernate.metamodel.binding.EntityBinding;
|
||||||
import org.hibernate.metamodel.source.MetadataImplementor;
|
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.JACCPreUpdateEventListener;
|
||||||
import org.hibernate.secure.internal.JACCSecurityListener;
|
import org.hibernate.secure.internal.JACCSecurityListener;
|
||||||
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
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.ServiceRegistryImplementor;
|
||||||
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
|
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare the HEM-specific event listeners.
|
* Hibernate EntityManager specific Integrator, performing JPA setup.
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class JpaIntegrator implements Integrator {
|
public class JpaIntegrator implements Integrator {
|
||||||
|
private ListenerFactory jpaListenerFactory;
|
||||||
|
private CallbackProcessor callbackProcessor;
|
||||||
|
private CallbackRegistry callbackRegistry;
|
||||||
|
|
||||||
private static final DuplicationStrategy JPA_DUPLICATION_STRATEGY = new DuplicationStrategy() {
|
private static final DuplicationStrategy JPA_DUPLICATION_STRATEGY = new DuplicationStrategy() {
|
||||||
@Override
|
@Override
|
||||||
public boolean areMatch(Object listener, Object original) {
|
public boolean areMatch(Object listener, Object original) {
|
||||||
|
@ -109,6 +133,7 @@ public class JpaIntegrator implements Integrator {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// then prepare listeners
|
// then prepare listeners
|
||||||
final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );
|
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();
|
Iterator classes = configuration.getClassMappings();
|
||||||
ReflectionManager reflectionManager = configuration.getReflectionManager();
|
|
||||||
while ( classes.hasNext() ) {
|
while ( classes.hasNext() ) {
|
||||||
PersistentClass clazz = (PersistentClass) classes.next();
|
final PersistentClass clazz = (PersistentClass) classes.next();
|
||||||
if ( clazz.getClassName() == null ) {
|
if ( clazz.getClassName() == null ) {
|
||||||
// we can have non java class persisted by hibernate
|
// we can have non java class persisted by hibernate
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
try {
|
callbackProcessor.processCallbacksForEntity( clazz.getClassName(), callbackRegistry );
|
||||||
callbackHandler.add( reflectionManager.classForName( clazz.getClassName(), this.getClass() ), reflectionManager );
|
|
||||||
}
|
|
||||||
catch (ClassNotFoundException e) {
|
|
||||||
throw new MappingException( "entity class not found: " + clazz.getNodeName(), e );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( EventType eventType : EventType.values() ) {
|
for ( EventType eventType : EventType.values() ) {
|
||||||
final EventListenerGroup eventListenerGroup = eventListenerRegistry.getEventListenerGroup( eventType );
|
final EventListenerGroup eventListenerGroup = eventListenerRegistry.getEventListenerGroup( eventType );
|
||||||
for ( Object listener : eventListenerGroup.listeners() ) {
|
for ( Object listener : eventListenerGroup.listeners() ) {
|
||||||
if ( CallbackHandlerConsumer.class.isInstance( listener ) ) {
|
if ( CallbackRegistryConsumer.class.isInstance( listener ) ) {
|
||||||
( (CallbackHandlerConsumer) listener ).setCallbackHandler( callbackHandler );
|
( (CallbackRegistryConsumer) listener ).injectCallbackRegistry( callbackRegistry );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,34 +285,40 @@ public class JpaIntegrator implements Integrator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final EntityCallbackHandler callbackHandler = new EntityCallbackHandler();
|
// handle JPA "entity listener classes"...
|
||||||
ClassLoaderService classLoaderSvc = serviceRegistry.getService(ClassLoaderService.class);
|
|
||||||
|
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() ) {
|
for ( EntityBinding binding : metadata.getEntityBindings() ) {
|
||||||
String name = binding.getEntity().getName(); // Should this be getClassName()?
|
callbackProcessor.processCallbacksForEntity( binding, callbackRegistry );
|
||||||
if (name == null) {
|
}
|
||||||
//we can have non java class persisted by hibernate
|
|
||||||
continue;
|
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 );
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
callbackHandler.add(classLoaderSvc.classForName(name), classLoaderSvc, binding);
|
|
||||||
}
|
|
||||||
catch (ClassLoadingException error) {
|
|
||||||
throw new MappingException( "entity class not found: " + name, error );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// 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
|
@Override
|
||||||
public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
|
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) {
|
private Object instantiate(String listenerImpl, ServiceRegistryImplementor serviceRegistry) {
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* 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).
|
* Marker interface for handling listener duplication checking (to avoid multiple registrations).
|
|
@ -21,7 +21,7 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.jpa.internal.event;
|
package org.hibernate.jpa.internal.event.core;
|
||||||
|
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
|
|
|
@ -21,13 +21,15 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.jpa.internal.event;
|
package org.hibernate.jpa.internal.event.core;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import org.hibernate.event.internal.DefaultDeleteEventListener;
|
import org.hibernate.event.internal.DefaultDeleteEventListener;
|
||||||
import org.hibernate.event.spi.DeleteEvent;
|
import org.hibernate.event.spi.DeleteEvent;
|
||||||
import org.hibernate.event.spi.EventSource;
|
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;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,25 +37,25 @@ import org.hibernate.persister.entity.EntityPersister;
|
||||||
*
|
*
|
||||||
* @author Emmanuel Bernard
|
* @author Emmanuel Bernard
|
||||||
*/
|
*/
|
||||||
public class JpaDeleteEventListener extends DefaultDeleteEventListener implements CallbackHandlerConsumer {
|
public class JpaDeleteEventListener extends DefaultDeleteEventListener implements CallbackRegistryConsumer {
|
||||||
private EntityCallbackHandler callbackHandler;
|
private CallbackRegistry callbackRegistry;
|
||||||
|
|
||||||
public void setCallbackHandler(EntityCallbackHandler callbackHandler) {
|
public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
|
||||||
this.callbackHandler = callbackHandler;
|
this.callbackRegistry = callbackRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaDeleteEventListener() {
|
public JpaDeleteEventListener() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaDeleteEventListener(EntityCallbackHandler callbackHandler) {
|
public JpaDeleteEventListener(CallbackRegistry callbackRegistry) {
|
||||||
this();
|
this();
|
||||||
this.callbackHandler = callbackHandler;
|
this.callbackRegistry = callbackRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean invokeDeleteLifecycle(EventSource session, Object entity, EntityPersister persister) {
|
protected boolean invokeDeleteLifecycle(EventSource session, Object entity, EntityPersister persister) {
|
||||||
callbackHandler.preRemove( entity );
|
callbackRegistry.preRemove( entity );
|
||||||
return super.invokeDeleteLifecycle( session, entity, persister );
|
return super.invokeDeleteLifecycle( session, entity, persister );
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,13 +21,15 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* 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.SessionFactory;
|
||||||
import org.hibernate.engine.spi.EntityEntry;
|
import org.hibernate.engine.spi.EntityEntry;
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.engine.spi.Status;
|
import org.hibernate.engine.spi.Status;
|
||||||
import org.hibernate.event.internal.DefaultFlushEntityEventListener;
|
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.metadata.ClassMetadata;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
@ -37,20 +39,20 @@ import org.hibernate.type.Type;
|
||||||
*
|
*
|
||||||
* @author Emmanuel Bernard
|
* @author Emmanuel Bernard
|
||||||
*/
|
*/
|
||||||
public class JpaFlushEntityEventListener extends DefaultFlushEntityEventListener implements CallbackHandlerConsumer {
|
public class JpaFlushEntityEventListener extends DefaultFlushEntityEventListener implements CallbackRegistryConsumer {
|
||||||
private EntityCallbackHandler callbackHandler;
|
private CallbackRegistry callbackRegistry;
|
||||||
|
|
||||||
public void setCallbackHandler(EntityCallbackHandler callbackHandler) {
|
public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
|
||||||
this.callbackHandler = callbackHandler;
|
this.callbackRegistry = callbackRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaFlushEntityEventListener() {
|
public JpaFlushEntityEventListener() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaFlushEntityEventListener(EntityCallbackHandler callbackHandler) {
|
public JpaFlushEntityEventListener(CallbackRegistry callbackRegistry) {
|
||||||
super();
|
super();
|
||||||
this.callbackHandler = callbackHandler;
|
this.callbackRegistry = callbackRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -62,7 +64,7 @@ public class JpaFlushEntityEventListener extends DefaultFlushEntityEventListener
|
||||||
EntityPersister persister) {
|
EntityPersister persister) {
|
||||||
boolean isDirty = false;
|
boolean isDirty = false;
|
||||||
if ( entry.getStatus() != Status.DELETED ) {
|
if ( entry.getStatus() != Status.DELETED ) {
|
||||||
if ( callbackHandler.preUpdate( entity ) ) {
|
if ( callbackRegistry.preUpdate( entity ) ) {
|
||||||
isDirty = copyState( entity, persister.getPropertyTypes(), values, session.getFactory() );
|
isDirty = copyState( entity, persister.getPropertyTypes(), values, session.getFactory() );
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.jpa.internal.event;
|
package org.hibernate.jpa.internal.event.core;
|
||||||
|
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
|
|
|
@ -21,32 +21,34 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.jpa.internal.event;
|
package org.hibernate.jpa.internal.event.core;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import org.hibernate.event.internal.DefaultMergeEventListener;
|
import org.hibernate.event.internal.DefaultMergeEventListener;
|
||||||
import org.hibernate.event.spi.EventSource;
|
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
|
* Overrides the LifeCycle OnSave call to call the PrePersist operation
|
||||||
*
|
*
|
||||||
* @author Emmanuel Bernard
|
* @author Emmanuel Bernard
|
||||||
*/
|
*/
|
||||||
public class JpaMergeEventListener extends DefaultMergeEventListener implements CallbackHandlerConsumer {
|
public class JpaMergeEventListener extends DefaultMergeEventListener implements CallbackRegistryConsumer {
|
||||||
private EntityCallbackHandler callbackHandler;
|
private CallbackRegistry callbackRegistry;
|
||||||
|
|
||||||
public void setCallbackHandler(EntityCallbackHandler callbackHandler) {
|
public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
|
||||||
this.callbackHandler = callbackHandler;
|
this.callbackRegistry = callbackRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaMergeEventListener() {
|
public JpaMergeEventListener() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaMergeEventListener(EntityCallbackHandler callbackHandler) {
|
public JpaMergeEventListener(CallbackRegistry callbackRegistry) {
|
||||||
super();
|
super();
|
||||||
this.callbackHandler = callbackHandler;
|
this.callbackRegistry = callbackRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -56,7 +58,7 @@ public class JpaMergeEventListener extends DefaultMergeEventListener implements
|
||||||
String entityName,
|
String entityName,
|
||||||
Object anything,
|
Object anything,
|
||||||
EventSource source) {
|
EventSource source) {
|
||||||
callbackHandler.preCreate( entity );
|
callbackRegistry.preCreate( entity );
|
||||||
return super.saveWithRequestedId( entity, requestedId, entityName, anything, source );
|
return super.saveWithRequestedId( entity, requestedId, entityName, anything, source );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +69,7 @@ public class JpaMergeEventListener extends DefaultMergeEventListener implements
|
||||||
Object anything,
|
Object anything,
|
||||||
EventSource source,
|
EventSource source,
|
||||||
boolean requiresImmediateIdAccess) {
|
boolean requiresImmediateIdAccess) {
|
||||||
callbackHandler.preCreate( entity );
|
callbackRegistry.preCreate( entity );
|
||||||
return super.saveWithGeneratedId( entity, entityName, anything, source, requiresImmediateIdAccess );
|
return super.saveWithGeneratedId( entity, entityName, anything, source, requiresImmediateIdAccess );
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.jpa.internal.event;
|
package org.hibernate.jpa.internal.event.core;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -34,6 +34,8 @@ import org.hibernate.engine.spi.CascadingAction;
|
||||||
import org.hibernate.engine.spi.CascadingActions;
|
import org.hibernate.engine.spi.CascadingActions;
|
||||||
import org.hibernate.event.internal.DefaultPersistEventListener;
|
import org.hibernate.event.internal.DefaultPersistEventListener;
|
||||||
import org.hibernate.event.spi.EventSource;
|
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;
|
import org.hibernate.type.CollectionType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,23 +43,23 @@ import org.hibernate.type.CollectionType;
|
||||||
*
|
*
|
||||||
* @author Emmanuel Bernard
|
* @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 static final Logger log = Logger.getLogger( JpaPersistEventListener.class );
|
||||||
|
|
||||||
private EntityCallbackHandler callbackHandler;
|
private CallbackRegistry callbackRegistry;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCallbackHandler(EntityCallbackHandler callbackHandler) {
|
public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
|
||||||
this.callbackHandler = callbackHandler;
|
this.callbackRegistry = callbackRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaPersistEventListener() {
|
public JpaPersistEventListener() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaPersistEventListener(EntityCallbackHandler callbackHandler) {
|
public JpaPersistEventListener(CallbackRegistry callbackRegistry) {
|
||||||
super();
|
super();
|
||||||
this.callbackHandler = callbackHandler;
|
this.callbackRegistry = callbackRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -67,7 +69,7 @@ public class JpaPersistEventListener extends DefaultPersistEventListener impleme
|
||||||
String entityName,
|
String entityName,
|
||||||
Object anything,
|
Object anything,
|
||||||
EventSource source) {
|
EventSource source) {
|
||||||
callbackHandler.preCreate( entity );
|
callbackRegistry.preCreate( entity );
|
||||||
return super.saveWithRequestedId( entity, requestedId, entityName, anything, source );
|
return super.saveWithRequestedId( entity, requestedId, entityName, anything, source );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +80,7 @@ public class JpaPersistEventListener extends DefaultPersistEventListener impleme
|
||||||
Object anything,
|
Object anything,
|
||||||
EventSource source,
|
EventSource source,
|
||||||
boolean requiresImmediateIdAccess) {
|
boolean requiresImmediateIdAccess) {
|
||||||
callbackHandler.preCreate( entity );
|
callbackRegistry.preCreate( entity );
|
||||||
return super.saveWithGeneratedId( entity, entityName, anything, source, requiresImmediateIdAccess );
|
return super.saveWithGeneratedId( entity, entityName, anything, source, requiresImmediateIdAccess );
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* 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.CascadingAction;
|
||||||
import org.hibernate.engine.spi.CascadingActions;
|
import org.hibernate.engine.spi.CascadingActions;
|
|
@ -21,32 +21,34 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* 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.PostDeleteEvent;
|
||||||
import org.hibernate.event.spi.PostDeleteEventListener;
|
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>
|
* @author <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
|
||||||
*/
|
*/
|
||||||
public class JpaPostDeleteEventListener implements PostDeleteEventListener, CallbackHandlerConsumer {
|
public class JpaPostDeleteEventListener implements PostDeleteEventListener, CallbackRegistryConsumer {
|
||||||
EntityCallbackHandler callbackHandler;
|
CallbackRegistry callbackRegistry;
|
||||||
|
|
||||||
public void setCallbackHandler(EntityCallbackHandler callbackHandler) {
|
public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
|
||||||
this.callbackHandler = callbackHandler;
|
this.callbackRegistry = callbackRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaPostDeleteEventListener() {
|
public JpaPostDeleteEventListener() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaPostDeleteEventListener(EntityCallbackHandler callbackHandler) {
|
public JpaPostDeleteEventListener(CallbackRegistry callbackRegistry) {
|
||||||
this.callbackHandler = callbackHandler;
|
this.callbackRegistry = callbackRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPostDelete(PostDeleteEvent event) {
|
public void onPostDelete(PostDeleteEvent event) {
|
||||||
Object entity = event.getEntity();
|
Object entity = event.getEntity();
|
||||||
callbackHandler.postRemove( entity );
|
callbackRegistry.postRemove( entity );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -21,33 +21,35 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* 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.PostInsertEvent;
|
||||||
import org.hibernate.event.spi.PostInsertEventListener;
|
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>
|
* @author <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
|
||||||
*/
|
*/
|
||||||
public class JpaPostInsertEventListener implements PostInsertEventListener, CallbackHandlerConsumer {
|
public class JpaPostInsertEventListener implements PostInsertEventListener, CallbackRegistryConsumer {
|
||||||
EntityCallbackHandler callbackHandler;
|
CallbackRegistry callbackRegistry;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCallbackHandler(EntityCallbackHandler callbackHandler) {
|
public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
|
||||||
this.callbackHandler = callbackHandler;
|
this.callbackRegistry = callbackRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaPostInsertEventListener() {
|
public JpaPostInsertEventListener() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaPostInsertEventListener(EntityCallbackHandler callbackHandler) {
|
public JpaPostInsertEventListener(CallbackRegistry callbackRegistry) {
|
||||||
this.callbackHandler = callbackHandler;
|
this.callbackRegistry = callbackRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPostInsert(PostInsertEvent event) {
|
public void onPostInsert(PostInsertEvent event) {
|
||||||
Object entity = event.getEntity();
|
Object entity = event.getEntity();
|
||||||
callbackHandler.postCreate( entity );
|
callbackRegistry.postCreate( entity );
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,34 +21,36 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* 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.PostLoadEvent;
|
||||||
import org.hibernate.event.spi.PostLoadEventListener;
|
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>
|
* @author <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
|
||||||
*/
|
*/
|
||||||
public class JpaPostLoadEventListener implements PostLoadEventListener, CallbackHandlerConsumer {
|
public class JpaPostLoadEventListener implements PostLoadEventListener, CallbackRegistryConsumer {
|
||||||
EntityCallbackHandler callbackHandler;
|
CallbackRegistry callbackRegistry;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCallbackHandler(EntityCallbackHandler callbackHandler) {
|
public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
|
||||||
this.callbackHandler = callbackHandler;
|
this.callbackRegistry = callbackRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaPostLoadEventListener() {
|
public JpaPostLoadEventListener() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaPostLoadEventListener(EntityCallbackHandler callbackHandler) {
|
public JpaPostLoadEventListener(CallbackRegistry callbackRegistry) {
|
||||||
this.callbackHandler = callbackHandler;
|
this.callbackRegistry = callbackRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPostLoad(PostLoadEvent event) {
|
public void onPostLoad(PostLoadEvent event) {
|
||||||
Object entity = event.getEntity();
|
Object entity = event.getEntity();
|
||||||
callbackHandler.postLoad( entity );
|
callbackRegistry.postLoad( entity );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* 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.EntityEntry;
|
||||||
import org.hibernate.engine.spi.Status;
|
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.PostCollectionUpdateEventListener;
|
||||||
import org.hibernate.event.spi.PostUpdateEvent;
|
import org.hibernate.event.spi.PostUpdateEvent;
|
||||||
import org.hibernate.event.spi.PostUpdateEventListener;
|
import org.hibernate.event.spi.PostUpdateEventListener;
|
||||||
|
import org.hibernate.jpa.internal.event.jpa.CallbackRegistryConsumer;
|
||||||
|
import org.hibernate.jpa.internal.event.jpa.CallbackRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of the post update listeners.
|
* Implementation of the post update listeners.
|
||||||
|
@ -43,23 +45,23 @@ import org.hibernate.event.spi.PostUpdateEventListener;
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class JpaPostUpdateEventListener
|
public class JpaPostUpdateEventListener
|
||||||
implements PostUpdateEventListener,
|
implements PostUpdateEventListener,
|
||||||
CallbackHandlerConsumer,
|
CallbackRegistryConsumer,
|
||||||
PostCollectionRecreateEventListener,
|
PostCollectionRecreateEventListener,
|
||||||
PostCollectionRemoveEventListener,
|
PostCollectionRemoveEventListener,
|
||||||
PostCollectionUpdateEventListener {
|
PostCollectionUpdateEventListener {
|
||||||
EntityCallbackHandler callbackHandler;
|
CallbackRegistry callbackRegistry;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCallbackHandler(EntityCallbackHandler callbackHandler) {
|
public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
|
||||||
this.callbackHandler = callbackHandler;
|
this.callbackRegistry = callbackRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaPostUpdateEventListener() {
|
public JpaPostUpdateEventListener() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaPostUpdateEventListener(EntityCallbackHandler callbackHandler) {
|
public JpaPostUpdateEventListener(CallbackRegistry callbackRegistry) {
|
||||||
this.callbackHandler = callbackHandler;
|
this.callbackRegistry = callbackRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -74,7 +76,7 @@ public class JpaPostUpdateEventListener
|
||||||
.getEntityEntries().get(entity);
|
.getEntityEntries().get(entity);
|
||||||
// mimic the preUpdate filter
|
// mimic the preUpdate filter
|
||||||
if ( Status.DELETED != entry.getStatus()) {
|
if ( Status.DELETED != entry.getStatus()) {
|
||||||
callbackHandler.postUpdate(entity);
|
callbackRegistry.postUpdate(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,32 +21,34 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.jpa.internal.event;
|
package org.hibernate.jpa.internal.event.core;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import org.hibernate.event.internal.DefaultSaveEventListener;
|
import org.hibernate.event.internal.DefaultSaveEventListener;
|
||||||
import org.hibernate.event.spi.EventSource;
|
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
|
* Overrides the LifeCycle OnSave call to call the PrePersist operation
|
||||||
*
|
*
|
||||||
* @author Emmanuel Bernard
|
* @author Emmanuel Bernard
|
||||||
*/
|
*/
|
||||||
public class JpaSaveEventListener extends DefaultSaveEventListener implements CallbackHandlerConsumer {
|
public class JpaSaveEventListener extends DefaultSaveEventListener implements CallbackRegistryConsumer {
|
||||||
private EntityCallbackHandler callbackHandler;
|
private CallbackRegistry callbackRegistry;
|
||||||
|
|
||||||
public void setCallbackHandler(EntityCallbackHandler callbackHandler) {
|
public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
|
||||||
this.callbackHandler = callbackHandler;
|
this.callbackRegistry = callbackRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaSaveEventListener() {
|
public JpaSaveEventListener() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaSaveEventListener(EntityCallbackHandler callbackHandler) {
|
public JpaSaveEventListener(CallbackRegistry callbackRegistry) {
|
||||||
super();
|
super();
|
||||||
this.callbackHandler = callbackHandler;
|
this.callbackRegistry = callbackRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -56,7 +58,7 @@ public class JpaSaveEventListener extends DefaultSaveEventListener implements Ca
|
||||||
String entityName,
|
String entityName,
|
||||||
Object anything,
|
Object anything,
|
||||||
EventSource source) {
|
EventSource source) {
|
||||||
callbackHandler.preCreate( entity );
|
callbackRegistry.preCreate( entity );
|
||||||
return super.saveWithRequestedId( entity, requestedId, entityName, anything, source );
|
return super.saveWithRequestedId( entity, requestedId, entityName, anything, source );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +69,7 @@ public class JpaSaveEventListener extends DefaultSaveEventListener implements Ca
|
||||||
Object anything,
|
Object anything,
|
||||||
EventSource source,
|
EventSource source,
|
||||||
boolean requiresImmediateIdAccess) {
|
boolean requiresImmediateIdAccess) {
|
||||||
callbackHandler.preCreate( entity );
|
callbackRegistry.preCreate( entity );
|
||||||
return super.saveWithGeneratedId( entity, entityName, anything, source, requiresImmediateIdAccess );
|
return super.saveWithGeneratedId( entity, entityName, anything, source, requiresImmediateIdAccess );
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,32 +21,34 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.jpa.internal.event;
|
package org.hibernate.jpa.internal.event.core;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import org.hibernate.event.internal.DefaultSaveOrUpdateEventListener;
|
import org.hibernate.event.internal.DefaultSaveOrUpdateEventListener;
|
||||||
import org.hibernate.event.spi.EventSource;
|
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
|
* Overrides the LifeCycle OnSave call to call the PrePersist operation
|
||||||
*
|
*
|
||||||
* @author Emmanuel Bernard
|
* @author Emmanuel Bernard
|
||||||
*/
|
*/
|
||||||
public class JpaSaveOrUpdateEventListener extends DefaultSaveOrUpdateEventListener implements CallbackHandlerConsumer {
|
public class JpaSaveOrUpdateEventListener extends DefaultSaveOrUpdateEventListener implements CallbackRegistryConsumer {
|
||||||
private EntityCallbackHandler callbackHandler;
|
private CallbackRegistry callbackRegistry;
|
||||||
|
|
||||||
public void setCallbackHandler(EntityCallbackHandler callbackHandler) {
|
public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
|
||||||
this.callbackHandler = callbackHandler;
|
this.callbackRegistry = callbackRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaSaveOrUpdateEventListener() {
|
public JpaSaveOrUpdateEventListener() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaSaveOrUpdateEventListener(EntityCallbackHandler callbackHandler) {
|
public JpaSaveOrUpdateEventListener(CallbackRegistry callbackRegistry) {
|
||||||
super();
|
super();
|
||||||
this.callbackHandler = callbackHandler;
|
this.callbackRegistry = callbackRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -56,7 +58,7 @@ public class JpaSaveOrUpdateEventListener extends DefaultSaveOrUpdateEventListen
|
||||||
String entityName,
|
String entityName,
|
||||||
Object anything,
|
Object anything,
|
||||||
EventSource source) {
|
EventSource source) {
|
||||||
callbackHandler.preCreate( entity );
|
callbackRegistry.preCreate( entity );
|
||||||
return super.saveWithRequestedId( entity, requestedId, entityName, anything, source );
|
return super.saveWithRequestedId( entity, requestedId, entityName, anything, source );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +69,7 @@ public class JpaSaveOrUpdateEventListener extends DefaultSaveOrUpdateEventListen
|
||||||
Object anything,
|
Object anything,
|
||||||
EventSource source,
|
EventSource source,
|
||||||
boolean requiresImmediateIdAccess) {
|
boolean requiresImmediateIdAccess) {
|
||||||
callbackHandler.preCreate( entity );
|
callbackRegistry.preCreate( entity );
|
||||||
return super.saveWithGeneratedId( entity, entityName, anything, source, requiresImmediateIdAccess );
|
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
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.jpa.internal.event;
|
package org.hibernate.jpa.internal.event.jpa;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import javax.persistence.PersistenceException;
|
||||||
import java.util.HashMap;
|
|
||||||
import javax.persistence.PostLoad;
|
import javax.persistence.PostLoad;
|
||||||
import javax.persistence.PostPersist;
|
import javax.persistence.PostPersist;
|
||||||
import javax.persistence.PostRemove;
|
import javax.persistence.PostRemove;
|
||||||
|
@ -32,19 +31,17 @@ import javax.persistence.PostUpdate;
|
||||||
import javax.persistence.PrePersist;
|
import javax.persistence.PrePersist;
|
||||||
import javax.persistence.PreRemove;
|
import javax.persistence.PreRemove;
|
||||||
import javax.persistence.PreUpdate;
|
import javax.persistence.PreUpdate;
|
||||||
|
import java.io.Serializable;
|
||||||
import org.hibernate.annotations.common.reflection.ReflectionManager;
|
import java.util.HashMap;
|
||||||
import org.hibernate.annotations.common.reflection.XClass;
|
|
||||||
import org.hibernate.metamodel.binding.EntityBinding;
|
|
||||||
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keep track of all lifecycle callbacks and listeners for a given persistence unit
|
* 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 <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
|
||||||
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"unchecked", "serial"})
|
@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[]> preCreates = new HashMap<Class, Callback[]>();
|
||||||
private HashMap<Class, Callback[]> postCreates = new HashMap<Class, Callback[]>();
|
private HashMap<Class, Callback[]> postCreates = new HashMap<Class, Callback[]>();
|
||||||
private HashMap<Class, Callback[]> preRemoves = 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[]> postUpdates = new HashMap<Class, Callback[]>();
|
||||||
private HashMap<Class, Callback[]> postLoads = 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) {
|
public boolean preCreate(Object bean) {
|
||||||
return callback( preCreates.get( bean.getClass() ), bean );
|
return callback( preCreates.get( bean.getClass() ), bean );
|
||||||
}
|
}
|
||||||
|
@ -103,11 +78,10 @@ public class EntityCallbackHandler implements Serializable {
|
||||||
return callback( postLoads.get( bean.getClass() ), bean );
|
return callback( postLoads.get( bean.getClass() ), bean );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean callback(Callback[] callbacks, Object bean) {
|
private boolean callback(Callback[] callbacks, Object bean) {
|
||||||
if ( callbacks != null && callbacks.length != 0 ) {
|
if ( callbacks != null && callbacks.length != 0 ) {
|
||||||
for ( Callback callback : callbacks ) {
|
for ( Callback callback : callbacks ) {
|
||||||
callback.invoke( bean );
|
callback.performCallback( bean );
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -116,19 +90,56 @@ public class EntityCallbackHandler implements Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCallback(
|
/* package */ void addEntityCallbacks(Class entityClass, Class annotationClass, Callback[] callbacks) {
|
||||||
XClass entity, HashMap<Class, Callback[]> map, Class annotation, ReflectionManager reflectionManager
|
final HashMap<Class, Callback[]> map = determineAppropriateCallbackMap( annotationClass );
|
||||||
) {
|
if ( map.containsKey( entityClass ) ) {
|
||||||
Callback[] callbacks = null;
|
throw new PersistenceException( "Error build callback listeners; entity [" + entityClass.getName() + " was already processed" );
|
||||||
callbacks = CallbackResolver.resolveCallback( entity, annotation, reflectionManager );
|
}
|
||||||
map.put( reflectionManager.toClass( entity ), callbacks );
|
map.put( entityClass, callbacks );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCallback( Class<?> entity,
|
private HashMap<Class, Callback[]> determineAppropriateCallbackMap(Class annotationClass) {
|
||||||
HashMap<Class, Callback[]> map,
|
if ( PrePersist.class.equals( annotationClass ) ) {
|
||||||
Class annotation,
|
return preCreates;
|
||||||
ClassLoaderService classLoaderService,
|
}
|
||||||
EntityBinding binding ) {
|
|
||||||
map.put(entity, CallbackResolver.resolveCallbacks(entity, annotation, classLoaderService, binding));
|
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
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* 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.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
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 <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
|
||||||
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class BeanCallback extends Callback {
|
public class EntityCallback implements Callback {
|
||||||
public BeanCallback(Method callbackMethod) {
|
private Method callbackMethod;
|
||||||
super( callbackMethod );
|
|
||||||
|
public EntityCallback(Method callbackMethod) {
|
||||||
|
this.callbackMethod = callbackMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invoke(Object bean) {
|
@Override
|
||||||
|
public void performCallback(Object entity) {
|
||||||
try {
|
try {
|
||||||
callbackMethod.invoke( bean, new Object[0] );
|
callbackMethod.invoke( entity );
|
||||||
}
|
}
|
||||||
catch (InvocationTargetException e) {
|
catch (InvocationTargetException e) {
|
||||||
//keep runtime exceptions as is
|
//keep runtime exceptions as is
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
* 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
|
* indicated by the @author tags or express copyright attribution
|
||||||
* statements applied by the authors. All third-party contributions are
|
* statements applied by the authors. All third-party contributions are
|
||||||
* distributed under license by Red Hat Inc.
|
* distributed under license by Red Hat Inc.
|
||||||
|
@ -21,7 +21,21 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* 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.Annotation;
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
|
@ -29,48 +43,46 @@ import java.lang.annotation.Target;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
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.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.annotations.common.reflection.ReflectionManager;
|
import org.hibernate.annotations.common.reflection.ReflectionManager;
|
||||||
import org.hibernate.annotations.common.reflection.XClass;
|
import org.hibernate.annotations.common.reflection.XClass;
|
||||||
import org.hibernate.annotations.common.reflection.XMethod;
|
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 <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,
|
private final ListenerFactory jpaListenerFactory;
|
||||||
CallbackResolver.class.getName());
|
private final ReflectionManager reflectionManager;
|
||||||
|
|
||||||
private static boolean useAnnotationAnnotatedByListener;
|
public LegacyCallbackProcessor(ListenerFactory jpaListenerFactory, ReflectionManager reflectionManager) {
|
||||||
|
this.jpaListenerFactory = jpaListenerFactory;
|
||||||
static {
|
this.reflectionManager = reflectionManager;
|
||||||
//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 CallbackResolver() {
|
@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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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<Callback> callbacks = new ArrayList<Callback>();
|
||||||
List<String> callbacksMethodNames = new ArrayList<String>(); //used to track overridden methods
|
List<String> callbacksMethodNames = new ArrayList<String>(); //used to track overridden methods
|
||||||
List<Class> orderedListeners = new ArrayList<Class>();
|
List<Class> orderedListeners = new ArrayList<Class>();
|
||||||
|
@ -89,7 +101,7 @@ public final class CallbackResolver {
|
||||||
if ( ! callbacksMethodNames.contains( methodName ) ) {
|
if ( ! callbacksMethodNames.contains( methodName ) ) {
|
||||||
//overridden method, remove the superclass overridden method
|
//overridden method, remove the superclass overridden method
|
||||||
if ( callback == null ) {
|
if ( callback == null ) {
|
||||||
callback = new BeanCallback( method );
|
callback = new EntityCallback( method );
|
||||||
Class returnType = method.getReturnType();
|
Class returnType = method.getReturnType();
|
||||||
Class[] args = method.getParameterTypes();
|
Class[] args = method.getParameterTypes();
|
||||||
if ( returnType != Void.TYPE || args.length != 0 ) {
|
if ( returnType != Void.TYPE || args.length != 0 ) {
|
||||||
|
@ -99,7 +111,7 @@ public final class CallbackResolver {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!method.isAccessible()) method.setAccessible(true);
|
if (!method.isAccessible()) method.setAccessible(true);
|
||||||
LOG.debugf("Adding %s as %s callback for entity %s",
|
log.debugf("Adding %s as %s callback for entity %s",
|
||||||
methodName,
|
methodName,
|
||||||
annotation.getSimpleName(),
|
annotation.getSimpleName(),
|
||||||
beanClass.getName());
|
beanClass.getName());
|
||||||
|
@ -158,21 +170,8 @@ public final class CallbackResolver {
|
||||||
if ( ! callbacksMethodNames.contains( methodName ) ) {
|
if ( ! callbacksMethodNames.contains( methodName ) ) {
|
||||||
//overridden method, remove the superclass overridden method
|
//overridden method, remove the superclass overridden method
|
||||||
if ( callback == null ) {
|
if ( callback == null ) {
|
||||||
try {
|
callback = new ListenerCallback( jpaListenerFactory.buildListener( listener ), method );
|
||||||
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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Class returnType = method.getReturnType();
|
Class returnType = method.getReturnType();
|
||||||
Class[] args = method.getParameterTypes();
|
Class[] args = method.getParameterTypes();
|
||||||
if ( returnType != Void.TYPE || args.length != 1 ) {
|
if ( returnType != Void.TYPE || args.length != 1 ) {
|
||||||
|
@ -182,7 +181,7 @@ public final class CallbackResolver {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!method.isAccessible()) method.setAccessible(true);
|
if (!method.isAccessible()) method.setAccessible(true);
|
||||||
LOG.debugf("Adding %s as %s callback for entity %s",
|
log.debugf("Adding %s as %s callback for entity %s",
|
||||||
methodName,
|
methodName,
|
||||||
annotation.getSimpleName(),
|
annotation.getSimpleName(),
|
||||||
beanClass.getName());
|
beanClass.getName());
|
||||||
|
@ -203,60 +202,17 @@ public final class CallbackResolver {
|
||||||
return callbacks.toArray( new Callback[ callbacks.size() ] );
|
return callbacks.toArray( new Callback[ callbacks.size() ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Callback[] resolveCallbacks( Class<?> entityClass,
|
private static boolean useAnnotationAnnotatedByListener;
|
||||||
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 Callback createListenerCallback( Class<?> entityClass,
|
static {
|
||||||
Class<?> callbackClass,
|
//check whether reading annotations of annotations is useful or not
|
||||||
Object listener,
|
useAnnotationAnnotatedByListener = false;
|
||||||
String methodName ) {
|
Target target = EntityListeners.class.getAnnotation( Target.class );
|
||||||
Class<?> callbackSuperclass = callbackClass.getSuperclass();
|
if ( target != null ) {
|
||||||
if (callbackSuperclass != null) {
|
for ( ElementType type : target.value() ) {
|
||||||
Callback callback = createListenerCallback(entityClass, callbackSuperclass, listener, methodName);
|
if ( type.equals( ElementType.ANNOTATION_TYPE ) ) useAnnotationAnnotatedByListener = true;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void getListeners(XClass currentClazz, List<Class> orderedListeners) {
|
private static void getListeners(XClass currentClazz, List<Class> orderedListeners) {
|
||||||
|
@ -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
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* 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.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
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 <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
|
||||||
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class ListenerCallback extends Callback {
|
public class ListenerCallback implements Callback {
|
||||||
protected transient Object listener;
|
private final Method callbackMethod;
|
||||||
|
private final Object listenerInstance;
|
||||||
|
|
||||||
public ListenerCallback(Method callbackMethod, Object listener) {
|
public ListenerCallback(Object listenerInstance, Method callbackMethod) {
|
||||||
super( callbackMethod );
|
this.listenerInstance = listenerInstance;
|
||||||
this.listener = listener;
|
this.callbackMethod = callbackMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invoke(Object bean) {
|
public void performCallback(Object entity) {
|
||||||
try {
|
try {
|
||||||
callbackMethod.invoke( listener, new Object[]{bean} );
|
callbackMethod.invoke( listenerInstance, entity );
|
||||||
}
|
}
|
||||||
catch (InvocationTargetException e) {
|
catch (InvocationTargetException e) {
|
||||||
//keep runtime exceptions as is
|
//keep runtime exceptions as is
|
||||||
|
@ -60,23 +59,4 @@ public class ListenerCallback extends Callback {
|
||||||
throw new RuntimeException( e );
|
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
|
* 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
|
* indicated by the @author tags or express copyright attribution
|
||||||
* statements applied by the authors. All third-party contributions are
|
* statements applied by the authors. All third-party contributions are
|
||||||
* distributed under license by Red Hat Inc.
|
* distributed under license by Red Hat Inc.
|
||||||
|
@ -21,11 +21,8 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* 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.cfg.Environment;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.ejb.AvailableSettings;
|
import org.hibernate.jpa.AvailableSettings;
|
||||||
import org.hibernate.jpa.internal.EntityManagerFactoryImpl;
|
import org.hibernate.jpa.internal.EntityManagerFactoryImpl;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.jpa.HibernatePersistenceProvider;
|
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