HHH-11259 - Improved CDI support including support for other types of managed beans;
HHH-12133 - Create ManagedBeanRegistry and ManagedBean; HHH-12134 - Convert entity listener CDI support to use ManagedBean/MenagedBeanRepository Initial ManagedBeanRegistry and ManagedBean impl; Conversion of JPA event Listeners to use ManagedBeanRegistry
This commit is contained in:
parent
b0c27562f4
commit
564ec55ca1
|
@ -16,6 +16,7 @@ import org.hibernate.boot.registry.classloading.internal.TcclLookupPrecedence;
|
|||
import org.hibernate.internal.log.DeprecationLogger;
|
||||
import org.hibernate.jpa.JpaCompliance;
|
||||
import org.hibernate.query.internal.ParameterMetadataImpl;
|
||||
import org.hibernate.resource.beans.spi.ExtendedBeanManager;
|
||||
import org.hibernate.resource.transaction.spi.TransactionCoordinator;
|
||||
import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder;
|
||||
import org.hibernate.tool.schema.JdbcMetadaAccessStrategy;
|
||||
|
@ -185,12 +186,22 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings {
|
|||
*
|
||||
* According to JPA, strictly, the BeanManager should be passed in
|
||||
* at boot-time and be ready for use at that time. However not all
|
||||
* environments can do this (WildFly for one). To accommodate such
|
||||
* environments, Hibernate provides an SPI via
|
||||
* {@link org.hibernate.jpa.event.spi.jpa.ExtendedBeanManager} that
|
||||
* can be used to provide delayed BeanManager access. Long story
|
||||
* short, this setting could be typed as BeanManager or as
|
||||
* {@link org.hibernate.jpa.event.spi.jpa.ExtendedBeanManager}.
|
||||
* environments can do this (WildFly e.g.). To accommodate such
|
||||
* environments, Hibernate provides 2 options:
|
||||
*
|
||||
* * a proprietary CDI extension SPI (that we have proposed to
|
||||
* the CDI spec group as a standard option) that can be used
|
||||
* to provide delayed BeanManager access. To use this solution,
|
||||
* the reference passed as the BeanManager during bootstrap
|
||||
* should be typed as {@link ExtendedBeanManager}
|
||||
* * delayed access to the BeanManager reference. Here, Hibernate
|
||||
* will not access the reference passed as the BeanManager during
|
||||
* bootstrap until it is first needed. Note however that this has
|
||||
* the effect of delaying any deployement problems until after
|
||||
* bootstrapping.
|
||||
*
|
||||
* This setting is used to configure Hibernate ORM's access to
|
||||
* the BeanManager (either directly or via {@link ExtendedBeanManager}).
|
||||
*/
|
||||
String CDI_BEAN_MANAGER = "javax.persistence.bean.manager";
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.jpa.event.internal.jpa;
|
||||
package org.hibernate.jpa.event.internal;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.ElementType;
|
||||
|
@ -24,10 +24,10 @@ import org.hibernate.annotations.common.reflection.ClassLoadingException;
|
|||
import org.hibernate.annotations.common.reflection.ReflectionManager;
|
||||
import org.hibernate.annotations.common.reflection.XClass;
|
||||
import org.hibernate.annotations.common.reflection.XMethod;
|
||||
import org.hibernate.jpa.event.spi.jpa.Callback;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackType;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackBuilder;
|
||||
import org.hibernate.jpa.event.spi.jpa.ListenerFactory;
|
||||
import org.hibernate.jpa.event.spi.Callback;
|
||||
import org.hibernate.jpa.event.spi.CallbackBuilder;
|
||||
import org.hibernate.jpa.event.spi.CallbackType;
|
||||
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
@ -40,11 +40,11 @@ import org.jboss.logging.Logger;
|
|||
public class CallbackBuilderLegacyImpl implements CallbackBuilder {
|
||||
private static final Logger log = Logger.getLogger( CallbackBuilderLegacyImpl.class );
|
||||
|
||||
private final ListenerFactory jpaListenerFactory;
|
||||
private final ManagedBeanRegistry managedBeanRegistry;
|
||||
private final ReflectionManager reflectionManager;
|
||||
|
||||
public CallbackBuilderLegacyImpl(ListenerFactory jpaListenerFactory, ReflectionManager reflectionManager) {
|
||||
this.jpaListenerFactory = jpaListenerFactory;
|
||||
public CallbackBuilderLegacyImpl(ManagedBeanRegistry managedBeanRegistry, ReflectionManager reflectionManager) {
|
||||
this.managedBeanRegistry = managedBeanRegistry;
|
||||
this.reflectionManager = reflectionManager;
|
||||
}
|
||||
|
||||
|
@ -75,15 +75,10 @@ public class CallbackBuilderLegacyImpl implements CallbackBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
// nothign to do
|
||||
}
|
||||
|
||||
public Callback[] resolveCallbacks(XClass beanClass, CallbackType callbackType, ReflectionManager reflectionManager) {
|
||||
List<Callback> callbacks = new ArrayList<Callback>();
|
||||
List<String> callbacksMethodNames = new ArrayList<String>(); //used to track overridden methods
|
||||
List<Class> orderedListeners = new ArrayList<Class>();
|
||||
List<Callback> callbacks = new ArrayList<>();
|
||||
List<String> callbacksMethodNames = new ArrayList<>();
|
||||
List<Class> orderedListeners = new ArrayList<>();
|
||||
XClass currentClazz = beanClass;
|
||||
boolean stopListeners = false;
|
||||
boolean stopDefaultListeners = false;
|
||||
|
@ -157,7 +152,7 @@ public class CallbackBuilderLegacyImpl implements CallbackBuilder {
|
|||
Callback callback = null;
|
||||
if ( listener != null ) {
|
||||
XClass xListener = reflectionManager.toXClass( listener );
|
||||
callbacksMethodNames = new ArrayList<String>();
|
||||
callbacksMethodNames = new ArrayList<>();
|
||||
List<XMethod> methods = xListener.getDeclaredMethods();
|
||||
for ( final XMethod xMethod : methods ) {
|
||||
if ( xMethod.isAnnotationPresent( callbackType.getCallbackAnnotation() ) ) {
|
||||
|
@ -167,7 +162,7 @@ public class CallbackBuilderLegacyImpl implements CallbackBuilder {
|
|||
//overridden method, remove the superclass overridden method
|
||||
if ( callback == null ) {
|
||||
callback = new ListenerCallback(
|
||||
jpaListenerFactory.buildListener( listener ),
|
||||
managedBeanRegistry.getBean( listener ),
|
||||
method,
|
||||
callbackType
|
||||
);
|
||||
|
@ -245,4 +240,4 @@ public class CallbackBuilderLegacyImpl implements CallbackBuilder {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,18 +1,18 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.jpa.event.internal.jpa;
|
||||
package org.hibernate.jpa.event.internal;
|
||||
|
||||
import java.util.HashMap;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import org.hibernate.jpa.event.spi.jpa.Callback;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistry;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackType;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackBuilder;
|
||||
import org.hibernate.jpa.event.spi.Callback;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistry;
|
||||
import org.hibernate.jpa.event.spi.CallbackType;
|
||||
import org.hibernate.jpa.event.spi.CallbackBuilder;
|
||||
|
||||
/**
|
||||
* Keep track of all lifecycle callbacks and listeners for a given persistence unit
|
|
@ -1,16 +1,16 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.jpa.event.internal.jpa;
|
||||
package org.hibernate.jpa.event.internal;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.hibernate.jpa.event.spi.jpa.Callback;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackType;
|
||||
import org.hibernate.jpa.event.spi.AbstractCallback;
|
||||
import org.hibernate.jpa.event.spi.CallbackType;
|
||||
|
||||
/**
|
||||
* Represents a JPA callback on the entity itself
|
||||
|
@ -18,9 +18,10 @@ import org.hibernate.jpa.event.spi.jpa.CallbackType;
|
|||
* @author <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EntityCallback extends AbstractCallback implements Callback {
|
||||
public class EntityCallback extends AbstractCallback {
|
||||
private final Method callbackMethod;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public EntityCallback(Method callbackMethod, CallbackType callbackType) {
|
||||
super( callbackType );
|
||||
this.callbackMethod = callbackMethod;
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.jpa.event.internal.jpa;
|
||||
package org.hibernate.jpa.event.internal;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.hibernate.jpa.event.spi.jpa.Callback;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackType;
|
||||
import org.hibernate.jpa.event.spi.jpa.Listener;
|
||||
import org.hibernate.jpa.event.spi.AbstractCallback;
|
||||
import org.hibernate.jpa.event.spi.CallbackType;
|
||||
import org.hibernate.resource.beans.spi.ManagedBean;
|
||||
|
||||
/**
|
||||
* Represents a JPA callback using a dedicated listener
|
||||
|
@ -19,20 +19,21 @@ import org.hibernate.jpa.event.spi.jpa.Listener;
|
|||
* @author <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ListenerCallback extends AbstractCallback implements Callback {
|
||||
public class ListenerCallback extends AbstractCallback {
|
||||
private final Method callbackMethod;
|
||||
private final Listener listenerInstance;
|
||||
private final ManagedBean listenerManagedBean;
|
||||
|
||||
public ListenerCallback(Listener listenerInstance, Method callbackMethod, CallbackType callbackType) {
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public ListenerCallback(ManagedBean listenerManagedBean, Method callbackMethod, CallbackType callbackType) {
|
||||
super( callbackType );
|
||||
this.listenerInstance = listenerInstance;
|
||||
this.listenerManagedBean = listenerManagedBean;
|
||||
this.callbackMethod = callbackMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performCallback(Object entity) {
|
||||
try {
|
||||
callbackMethod.invoke( listenerInstance.getListener(), entity );
|
||||
callbackMethod.invoke( listenerManagedBean.getBeanInstance(), entity );
|
||||
return true;
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
|
@ -44,8 +45,11 @@ public class ListenerCallback extends AbstractCallback implements Callback {
|
|||
throw new RuntimeException( e.getTargetException() );
|
||||
}
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException( e );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,8 +11,8 @@ import java.io.Serializable;
|
|||
import org.hibernate.event.internal.DefaultDeleteEventListener;
|
||||
import org.hibernate.event.spi.DeleteEvent;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistry;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistry;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,8 +12,8 @@ import org.hibernate.engine.spi.EntityEntry;
|
|||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.engine.spi.Status;
|
||||
import org.hibernate.event.internal.DefaultFlushEntityEventListener;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistry;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistry;
|
||||
import org.hibernate.metadata.ClassMetadata;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.type.Type;
|
||||
|
|
|
@ -10,8 +10,8 @@ import java.io.Serializable;
|
|||
|
||||
import org.hibernate.event.internal.DefaultMergeEventListener;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistry;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistry;
|
||||
|
||||
/**
|
||||
* Overrides the LifeCycle OnSave call to call the PrePersist operation
|
||||
|
|
|
@ -15,8 +15,8 @@ import org.hibernate.engine.spi.CascadingAction;
|
|||
import org.hibernate.engine.spi.CascadingActions;
|
||||
import org.hibernate.event.internal.DefaultPersistEventListener;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistry;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistry;
|
||||
import org.hibernate.type.CollectionType;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
|
|
@ -8,9 +8,9 @@ package org.hibernate.jpa.event.internal.core;
|
|||
|
||||
import org.hibernate.event.spi.PostDeleteEvent;
|
||||
import org.hibernate.event.spi.PostDeleteEventListener;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistry;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackType;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistry;
|
||||
import org.hibernate.jpa.event.spi.CallbackType;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,9 +8,9 @@ package org.hibernate.jpa.event.internal.core;
|
|||
|
||||
import org.hibernate.event.spi.PostInsertEvent;
|
||||
import org.hibernate.event.spi.PostInsertEventListener;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistry;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackType;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistry;
|
||||
import org.hibernate.jpa.event.spi.CallbackType;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,8 +8,8 @@ package org.hibernate.jpa.event.internal.core;
|
|||
|
||||
import org.hibernate.event.spi.PostLoadEvent;
|
||||
import org.hibernate.event.spi.PostLoadEventListener;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistry;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistry;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
|
||||
|
|
|
@ -17,9 +17,9 @@ import org.hibernate.event.spi.PostCollectionUpdateEvent;
|
|||
import org.hibernate.event.spi.PostCollectionUpdateEventListener;
|
||||
import org.hibernate.event.spi.PostUpdateEvent;
|
||||
import org.hibernate.event.spi.PostUpdateEventListener;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistry;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackType;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistry;
|
||||
import org.hibernate.jpa.event.spi.CallbackType;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,8 +10,8 @@ import java.io.Serializable;
|
|||
|
||||
import org.hibernate.event.internal.DefaultSaveEventListener;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistry;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistry;
|
||||
|
||||
/**
|
||||
* Overrides the LifeCycle OnSave call to call the PrePersist operation
|
||||
|
|
|
@ -10,8 +10,8 @@ import java.io.Serializable;
|
|||
|
||||
import org.hibernate.event.internal.DefaultSaveOrUpdateEventListener;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistry;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistry;
|
||||
|
||||
/**
|
||||
* Overrides the LifeCycle OnSave call to call the PrePersist operation
|
||||
|
|
|
@ -1,126 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.jpa.event.internal.jpa;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
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 org.hibernate.jpa.event.spi.jpa.Listener;
|
||||
import org.hibernate.jpa.event.spi.jpa.ListenerFactory;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* CDI-based implementation of the ListenerFactory contract. This implementation
|
||||
* delayes access to the CDI BeanManager until first need.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class ListenerFactoryBeanManagerDelayedImpl implements ListenerFactory {
|
||||
private static final Logger log = Logger.getLogger( ListenerFactoryBeanManagerDelayedImpl.class );
|
||||
|
||||
private final BeanManager beanManager;
|
||||
private final Map<Class,ListenerImpl> listenerMap = new ConcurrentHashMap<Class, ListenerImpl>();
|
||||
|
||||
/**
|
||||
* Used via reflection from JpaIntegrator, the intent being to isolate CDI dependency
|
||||
* to just this class and its delegates in the case that a BeanManager is passed.
|
||||
*
|
||||
* @param reference The BeanManager reference
|
||||
*
|
||||
* @return A instantiated ListenerFactoryBeanManagerImpl
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public static ListenerFactoryBeanManagerDelayedImpl fromBeanManagerReference(Object reference) {
|
||||
if ( !BeanManager.class.isInstance( reference ) ) {
|
||||
throw new IllegalArgumentException(
|
||||
"Expecting BeanManager reference that implements CDI BeanManager contract : " +
|
||||
reference
|
||||
);
|
||||
}
|
||||
return new ListenerFactoryBeanManagerDelayedImpl( (BeanManager) reference );
|
||||
}
|
||||
|
||||
public ListenerFactoryBeanManagerDelayedImpl(BeanManager beanManager) {
|
||||
this.beanManager = beanManager;
|
||||
log.debugf( "Delayed access requested to CDI BeanManager : " + beanManager );
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Listener<T> buildListener(Class<T> listenerClass) {
|
||||
ListenerImpl listenerImpl = listenerMap.get( listenerClass );
|
||||
if ( listenerImpl == null ) {
|
||||
listenerImpl = new ListenerImpl( listenerClass );
|
||||
listenerMap.put( listenerClass, listenerImpl );
|
||||
}
|
||||
return (Listener<T>) listenerImpl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
for ( ListenerImpl listenerImpl : listenerMap.values() ) {
|
||||
listenerImpl.release();
|
||||
}
|
||||
listenerMap.clear();
|
||||
}
|
||||
|
||||
private class ListenerImpl<T> implements Listener<T> {
|
||||
private final Class<T> listenerClass;
|
||||
|
||||
private boolean initialized = false;
|
||||
|
||||
private InjectionTarget<T> injectionTarget;
|
||||
private CreationalContext<T> creationalContext;
|
||||
private T listenerInstance;
|
||||
|
||||
private ListenerImpl(Class<T> listenerClass) {
|
||||
this.listenerClass = listenerClass;
|
||||
log.debugf( "Delayed CDI listener built : " + listenerClass );
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
log.debug( "Initializing delayed CDI listener on first use : " + listenerClass );
|
||||
AnnotatedType<T> annotatedType = beanManager.createAnnotatedType( listenerClass );
|
||||
this.injectionTarget = beanManager.createInjectionTarget( annotatedType );
|
||||
this.creationalContext = beanManager.createCreationalContext( null );
|
||||
|
||||
this.listenerInstance = injectionTarget.produce( creationalContext );
|
||||
injectionTarget.inject( this.listenerInstance, creationalContext );
|
||||
|
||||
injectionTarget.postConstruct( this.listenerInstance );
|
||||
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getListener() {
|
||||
if ( !initialized ) {
|
||||
initialize();
|
||||
}
|
||||
return listenerInstance;
|
||||
}
|
||||
|
||||
public void release() {
|
||||
if ( !initialized ) {
|
||||
log.debug( "Skipping release for CDI listener [" + listenerClass + "] as it was not initialized" );
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug( "Releasing CDI listener : " + listenerClass );
|
||||
|
||||
injectionTarget.preDestroy( listenerInstance );
|
||||
injectionTarget.dispose( listenerInstance );
|
||||
creationalContext.release();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,130 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.jpa.event.internal.jpa;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
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 org.hibernate.HibernateException;
|
||||
import org.hibernate.jpa.event.spi.jpa.ExtendedBeanManager;
|
||||
import org.hibernate.jpa.event.spi.jpa.Listener;
|
||||
import org.hibernate.jpa.event.spi.jpa.ListenerFactory;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* CDI-based implementation of the ListenerFactory contract. Further, this
|
||||
* implementation leverages the ExtendedBeanManager contract to delay CDI calls.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class ListenerFactoryBeanManagerExtendedImpl implements ListenerFactory, ExtendedBeanManager.LifecycleListener {
|
||||
private static final Logger log = Logger.getLogger( ListenerFactoryBeanManagerExtendedImpl.class );
|
||||
|
||||
private final Map<Class,ListenerImpl> listenerMap = new ConcurrentHashMap<Class, ListenerImpl>();
|
||||
|
||||
/**
|
||||
* Used via reflection from JpaIntegrator, the intent being to isolate CDI dependency
|
||||
* to just this class and its delegates in the case that a BeanManager is passed.
|
||||
*
|
||||
* @param reference The BeanManager reference
|
||||
*
|
||||
* @return A instantiated ListenerFactoryBeanManagerImpl
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public static ListenerFactoryBeanManagerExtendedImpl fromBeanManagerReference(Object reference) {
|
||||
if ( !ExtendedBeanManager.class.isInstance( reference ) ) {
|
||||
throw new IllegalArgumentException(
|
||||
"Expecting BeanManager reference that implements optional ExtendedBeanManager contract : " +
|
||||
reference
|
||||
);
|
||||
}
|
||||
return new ListenerFactoryBeanManagerExtendedImpl( (ExtendedBeanManager) reference );
|
||||
}
|
||||
|
||||
public ListenerFactoryBeanManagerExtendedImpl(ExtendedBeanManager beanManager) {
|
||||
beanManager.registerLifecycleListener( this );
|
||||
log.debugf( "ExtendedBeanManager access requested to CDI BeanManager : " + beanManager );
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Listener<T> buildListener(Class<T> listenerClass) {
|
||||
ListenerImpl listenerImpl = listenerMap.get( listenerClass );
|
||||
if ( listenerImpl == null ) {
|
||||
listenerImpl = new ListenerImpl( listenerClass );
|
||||
listenerMap.put( listenerClass, listenerImpl );
|
||||
}
|
||||
return (Listener<T>) listenerImpl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
for ( ListenerImpl listenerImpl : listenerMap.values() ) {
|
||||
listenerImpl.release();
|
||||
}
|
||||
listenerMap.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beanManagerInitialized(BeanManager beanManager) {
|
||||
for ( ListenerImpl listenerImpl : listenerMap.values() ) {
|
||||
listenerImpl.initialize( beanManager );
|
||||
}
|
||||
}
|
||||
|
||||
private static class ListenerImpl<T> implements Listener<T> {
|
||||
private final Class<T> listenerClass;
|
||||
|
||||
private boolean initialized = false;
|
||||
|
||||
private InjectionTarget<T> injectionTarget;
|
||||
private CreationalContext<T> creationalContext;
|
||||
private T listenerInstance;
|
||||
|
||||
private ListenerImpl(Class<T> listenerClass) {
|
||||
this.listenerClass = listenerClass;
|
||||
}
|
||||
|
||||
public void initialize(BeanManager beanManager) {
|
||||
AnnotatedType<T> annotatedType = beanManager.createAnnotatedType( listenerClass );
|
||||
this.injectionTarget = beanManager.createInjectionTarget( annotatedType );
|
||||
this.creationalContext = beanManager.createCreationalContext( null );
|
||||
|
||||
this.listenerInstance = injectionTarget.produce( creationalContext );
|
||||
injectionTarget.inject( this.listenerInstance, creationalContext );
|
||||
|
||||
injectionTarget.postConstruct( this.listenerInstance );
|
||||
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getListener() {
|
||||
if ( !initialized ) {
|
||||
throw new HibernateException( "CDI not initialized as expected" );
|
||||
}
|
||||
return listenerInstance;
|
||||
}
|
||||
|
||||
public void release() {
|
||||
if ( !initialized ) {
|
||||
// log
|
||||
return;
|
||||
}
|
||||
|
||||
injectionTarget.preDestroy( listenerInstance );
|
||||
injectionTarget.dispose( listenerInstance );
|
||||
creationalContext.release();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.jpa.event.internal.jpa;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
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 org.hibernate.jpa.event.spi.jpa.Listener;
|
||||
import org.hibernate.jpa.event.spi.jpa.ListenerFactory;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* CDI-based implementation of the ListenerFactory contract. This CDI-based
|
||||
* implementation works in the JPA standard prescribed manner.
|
||||
* <p/>
|
||||
* See {@link ListenerFactoryBeanManagerExtendedImpl} for an alt implementation that
|
||||
* is still JPA compliant, but that works based on delayed CDI calls. Works
|
||||
* on a non-CDI-defined CDI extension; we plan to propose this extension to the
|
||||
* CDI expert group for the next CDI iteration
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class ListenerFactoryBeanManagerStandardImpl implements ListenerFactory {
|
||||
private static final Logger log = Logger.getLogger( ListenerFactoryBeanManagerStandardImpl.class );
|
||||
|
||||
private final BeanManager beanManager;
|
||||
private final Map<Class,ListenerImpl> listenerMap = new ConcurrentHashMap<Class, ListenerImpl>();
|
||||
|
||||
/**
|
||||
* Used via reflection from JpaIntegrator, the intent being to isolate CDI dependency
|
||||
* to just this class and its delegates in the case that a BeanManager is passed.
|
||||
*
|
||||
* @param reference The BeanManager reference
|
||||
*
|
||||
* @return A instantiated ListenerFactoryBeanManagerImpl
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public static ListenerFactoryBeanManagerStandardImpl fromBeanManagerReference(Object reference) {
|
||||
if ( !BeanManager.class.isInstance( reference ) ) {
|
||||
throw new IllegalArgumentException(
|
||||
"Expecting BeanManager reference that implements CDI BeanManager contract : " +
|
||||
reference
|
||||
);
|
||||
}
|
||||
return new ListenerFactoryBeanManagerStandardImpl( (BeanManager) reference );
|
||||
}
|
||||
|
||||
public ListenerFactoryBeanManagerStandardImpl(BeanManager beanManager) {
|
||||
this.beanManager = beanManager;
|
||||
log.debugf( "Standard access requested to CDI BeanManager : " + beanManager );
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Listener<T> buildListener(Class<T> listenerClass) {
|
||||
ListenerImpl listenerImpl = listenerMap.get( listenerClass );
|
||||
if ( listenerImpl == null ) {
|
||||
listenerImpl = new ListenerImpl( listenerClass );
|
||||
listenerMap.put( listenerClass, listenerImpl );
|
||||
}
|
||||
return (Listener<T>) listenerImpl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
for ( ListenerImpl listenerImpl : listenerMap.values() ) {
|
||||
listenerImpl.release();
|
||||
}
|
||||
listenerMap.clear();
|
||||
}
|
||||
|
||||
private class ListenerImpl<T> implements Listener<T> {
|
||||
private final InjectionTarget<T> injectionTarget;
|
||||
private final CreationalContext<T> creationalContext;
|
||||
private final T listenerInstance;
|
||||
|
||||
private ListenerImpl(Class<T> listenerClass) {
|
||||
AnnotatedType<T> annotatedType = beanManager.createAnnotatedType( listenerClass );
|
||||
this.injectionTarget = beanManager.createInjectionTarget( annotatedType );
|
||||
this.creationalContext = beanManager.createCreationalContext( null );
|
||||
|
||||
this.listenerInstance = injectionTarget.produce( creationalContext );
|
||||
injectionTarget.inject( this.listenerInstance, creationalContext );
|
||||
|
||||
injectionTarget.postConstruct( this.listenerInstance );
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getListener() {
|
||||
return listenerInstance;
|
||||
}
|
||||
|
||||
public void release() {
|
||||
injectionTarget.preDestroy( listenerInstance );
|
||||
injectionTarget.dispose( listenerInstance );
|
||||
creationalContext.release();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.jpa.event.internal.jpa;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import org.hibernate.jpa.event.spi.jpa.Listener;
|
||||
import org.hibernate.jpa.event.spi.jpa.ListenerFactory;
|
||||
|
||||
/**
|
||||
* Standard implementation of the ListenerFactory contract using simple instantiation.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ListenerFactoryStandardImpl implements ListenerFactory {
|
||||
private final ConcurrentHashMap<Class,ListenerImpl> listenerInstances = new ConcurrentHashMap<Class,ListenerImpl>();
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Listener<T> buildListener(Class<T> listenerClass) {
|
||||
ListenerImpl listenerImpl = listenerInstances.get( listenerClass );
|
||||
if ( listenerImpl == null ) {
|
||||
try {
|
||||
T listenerInstance = listenerClass.newInstance();
|
||||
listenerImpl = new ListenerImpl( listenerInstance );
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new PersistenceException(
|
||||
"Unable to create instance of " + listenerClass.getName() + " as a JPA callback listener",
|
||||
e
|
||||
);
|
||||
}
|
||||
ListenerImpl existing = listenerInstances.putIfAbsent(
|
||||
listenerClass,
|
||||
listenerImpl
|
||||
);
|
||||
if ( existing != null ) {
|
||||
listenerImpl = existing;
|
||||
}
|
||||
}
|
||||
return (Listener<T>) listenerImpl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
listenerInstances.clear();
|
||||
}
|
||||
|
||||
private static class ListenerImpl<T> implements Listener<T> {
|
||||
private final T listenerInstance;
|
||||
|
||||
public ListenerImpl(T listenerInstance) {
|
||||
this.listenerInstance = listenerInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getListener() {
|
||||
return listenerInstance;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.jpa.event.internal.jpa;
|
||||
|
||||
/**
|
||||
* Classes for integrating with JPA event callbacks
|
||||
*/
|
|
@ -1,29 +1,24 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.jpa.event.internal.jpa;
|
||||
|
||||
import org.hibernate.jpa.event.spi.jpa.Callback;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackType;
|
||||
package org.hibernate.jpa.event.spi;
|
||||
|
||||
/**
|
||||
* Abstract support for Callback implementations
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractCallback implements Callback {
|
||||
private final CallbackType callbackType;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public AbstractCallback(CallbackType callbackType) {
|
||||
this.callbackType = callbackType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallbackType getCallbackType() {
|
||||
return callbackType;
|
|
@ -1,35 +1,27 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.jpa.event.spi.jpa;
|
||||
package org.hibernate.jpa.event.spi;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Represents a JPA event callback (the method).
|
||||
* <p/>
|
||||
*
|
||||
* Generally there are 2 flavors of this; either an annotated method on the entity itself
|
||||
* or an annotated method on a separate "listener" class. This contract unifies both of
|
||||
* these cases.
|
||||
* or an annotated method on a separate "listener" class. This contract presents
|
||||
* a unified abstraction for both cases
|
||||
*
|
||||
* @author <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface Callback extends Serializable {
|
||||
/**
|
||||
* Is this callback active (will it do anything)?
|
||||
*
|
||||
* @return {@code true} if the callback is active, {@code false} otherwise.
|
||||
*
|
||||
* @deprecated I can actually find no usages of this method and have no idea
|
||||
* why it is here :)
|
||||
* The type of callback (pre-update, pre-persist, etc) handled
|
||||
*/
|
||||
@Deprecated
|
||||
boolean isActive();
|
||||
|
||||
CallbackType getCallbackType();
|
||||
|
||||
/**
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.jpa.event.spi.jpa;
|
||||
package org.hibernate.jpa.event.spi;
|
||||
|
||||
/**
|
||||
* Contract for walking an entity hierarchy and building a list of JPA callbacks
|
||||
|
@ -27,6 +27,4 @@ public interface CallbackBuilder {
|
|||
}
|
||||
|
||||
void buildCallbacksForEntity(String entityName, CallbackRegistrar callbackRegistrar);
|
||||
|
||||
void release();
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.jpa.event.spi.jpa;
|
||||
package org.hibernate.jpa.event.spi;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.jpa.event.spi.jpa;
|
||||
package org.hibernate.jpa.event.spi;
|
||||
|
||||
import org.hibernate.jpa.event.internal.core.HibernateEntityManagerEventListener;
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.jpa.event.spi.jpa;
|
||||
package org.hibernate.jpa.event.spi;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import javax.persistence.PostLoad;
|
|
@ -25,6 +25,8 @@ import org.hibernate.event.service.spi.EventListenerRegistry;
|
|||
import org.hibernate.event.spi.EventType;
|
||||
import org.hibernate.integrator.spi.Integrator;
|
||||
import org.hibernate.jpa.AvailableSettings;
|
||||
import org.hibernate.jpa.event.internal.CallbackBuilderLegacyImpl;
|
||||
import org.hibernate.jpa.event.internal.CallbackRegistryImpl;
|
||||
import org.hibernate.jpa.event.internal.core.HibernateEntityManagerEventListener;
|
||||
import org.hibernate.jpa.event.internal.core.JpaAutoFlushEventListener;
|
||||
import org.hibernate.jpa.event.internal.core.JpaDeleteEventListener;
|
||||
|
@ -39,13 +41,8 @@ import org.hibernate.jpa.event.internal.core.JpaPostLoadEventListener;
|
|||
import org.hibernate.jpa.event.internal.core.JpaPostUpdateEventListener;
|
||||
import org.hibernate.jpa.event.internal.core.JpaSaveEventListener;
|
||||
import org.hibernate.jpa.event.internal.core.JpaSaveOrUpdateEventListener;
|
||||
import org.hibernate.jpa.event.internal.jpa.CallbackBuilderLegacyImpl;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackRegistryConsumer;
|
||||
import org.hibernate.jpa.event.internal.jpa.CallbackRegistryImpl;
|
||||
import org.hibernate.jpa.event.spi.jpa.CallbackBuilder;
|
||||
import org.hibernate.jpa.event.spi.jpa.ListenerFactory;
|
||||
import org.hibernate.jpa.event.spi.jpa.ListenerFactoryBuilder;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
|
||||
|
||||
|
@ -55,8 +52,6 @@ import org.hibernate.service.spi.SessionFactoryServiceRegistry;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class JpaIntegrator implements Integrator {
|
||||
private ListenerFactory jpaListenerFactory;
|
||||
private CallbackBuilder callbackBuilder;
|
||||
private CallbackRegistryImpl callbackRegistry;
|
||||
private CascadeStyle oldPersistCascadeStyle;
|
||||
|
||||
|
@ -132,8 +127,9 @@ public class JpaIntegrator implements Integrator {
|
|||
.getReflectionManager();
|
||||
|
||||
this.callbackRegistry = new CallbackRegistryImpl();
|
||||
this.jpaListenerFactory = ListenerFactoryBuilder.buildListenerFactory( sessionFactory.getSessionFactoryOptions() );
|
||||
this.callbackBuilder = new CallbackBuilderLegacyImpl( jpaListenerFactory, reflectionManager );
|
||||
|
||||
final CallbackBuilder callbackBuilder = new CallbackBuilderLegacyImpl( serviceRegistry.getService( ManagedBeanRegistry.class ), reflectionManager );
|
||||
|
||||
for ( PersistentClass persistentClass : metadata.getEntityBindings() ) {
|
||||
if ( persistentClass.getClassName() == null ) {
|
||||
// we can have non java class persisted by hibernate
|
||||
|
@ -168,12 +164,6 @@ public class JpaIntegrator implements Integrator {
|
|||
if ( callbackRegistry != null ) {
|
||||
callbackRegistry.release();
|
||||
}
|
||||
if ( callbackBuilder != null ) {
|
||||
callbackBuilder.release();
|
||||
}
|
||||
if ( jpaListenerFactory != null ) {
|
||||
jpaListenerFactory.release();
|
||||
}
|
||||
}
|
||||
|
||||
private Object instantiate(String listenerImpl, ServiceRegistryImplementor serviceRegistry) {
|
||||
|
|
|
@ -6,32 +6,9 @@
|
|||
*/
|
||||
package org.hibernate.jpa.event.spi.jpa;
|
||||
|
||||
import javax.enterprise.inject.spi.BeanManager;
|
||||
|
||||
/**
|
||||
* This contract and the nested LifecycleListener contract represent the changes
|
||||
* we'd like to propose to the CDI spec. The idea being simply to allow contextual
|
||||
* registration of BeanManager lifecycle callbacks
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @deprecated Use {@link org.hibernate.resource.beans.spi.ExtendedBeanManager} instead
|
||||
*/
|
||||
public interface ExtendedBeanManager {
|
||||
/**
|
||||
* Register a BeanManager LifecycleListener
|
||||
*
|
||||
* @param lifecycleListener The listener to register
|
||||
*/
|
||||
void registerLifecycleListener(LifecycleListener lifecycleListener);
|
||||
|
||||
/**
|
||||
* Contract for things interested in receiving notifications of
|
||||
* BeanManager lifecycle events.
|
||||
* <p/>
|
||||
* A "beanManagerDestroyed" notifications would probably also be generally
|
||||
* useful, although we do not need it here and not sure WildFly can really
|
||||
* tell us that reliably.
|
||||
*/
|
||||
interface LifecycleListener {
|
||||
void beanManagerInitialized(BeanManager beanManager);
|
||||
}
|
||||
@Deprecated
|
||||
public interface ExtendedBeanManager extends org.hibernate.resource.beans.spi.ExtendedBeanManager {
|
||||
}
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.jpa.event.spi.jpa;
|
||||
|
||||
/**
|
||||
* Contract for building instances of JPA callback listener classes.
|
||||
* <p/>
|
||||
* Listener instances should be uniqued by Class such that the same instance is
|
||||
* returned for any calls to {@link #buildListener} with the same class.
|
||||
*
|
||||
* @see javax.persistence.EntityListeners
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ListenerFactory {
|
||||
<T> Listener<T> buildListener(Class<T> listenerClass);
|
||||
void release();
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.jpa.event.spi.jpa;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.boot.spi.SessionFactoryOptions;
|
||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||
import org.hibernate.engine.config.spi.StandardConverters;
|
||||
import org.hibernate.jpa.AvailableSettings;
|
||||
import org.hibernate.jpa.event.internal.jpa.ListenerFactoryStandardImpl;
|
||||
|
||||
/**
|
||||
* Builder for ListenerFactory based on configuration options
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ListenerFactoryBuilder {
|
||||
|
||||
public static ListenerFactory buildListenerFactory(SessionFactoryOptions options) {
|
||||
final Object beanManagerRef = options.getBeanManagerReference();
|
||||
if ( beanManagerRef == null ) {
|
||||
return new ListenerFactoryStandardImpl();
|
||||
}
|
||||
else if ( ExtendedBeanManager.class.isInstance( beanManagerRef ) ) {
|
||||
return buildExtendedBeanManagerListenerFactory( beanManagerRef );
|
||||
}
|
||||
else {
|
||||
final boolean delayAccessToCdi = options.getServiceRegistry()
|
||||
.getService( ConfigurationService.class )
|
||||
.getSetting( AvailableSettings.DELAY_CDI_ACCESS, StandardConverters.BOOLEAN, false );
|
||||
if ( delayAccessToCdi ) {
|
||||
return buildDelayedBeanManagerListenerFactory( beanManagerRef );
|
||||
}
|
||||
else {
|
||||
return buildStandardBeanManagerListenerFactory( beanManagerRef );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final String CDI_LISTENER_FACTORY_EXTENDED_CLASS = "org.hibernate.jpa.event.internal.jpa.ListenerFactoryBeanManagerExtendedImpl";
|
||||
private static final String CDI_LISTENER_FACTORY_STANDARD_CLASS = "org.hibernate.jpa.event.internal.jpa.ListenerFactoryBeanManagerStandardImpl";
|
||||
private static final String CDI_LISTENER_FACTORY_DELAYED_CLASS = "org.hibernate.jpa.event.internal.jpa.ListenerFactoryBeanManagerDelayedImpl";
|
||||
private static final String CDI_LISTENER_FACTORY_METHOD_NAME = "fromBeanManagerReference";
|
||||
|
||||
|
||||
private static ListenerFactory buildExtendedBeanManagerListenerFactory(Object beanManagerRef) {
|
||||
return buildBeanManagerListenerFactory( beanManagerRef, CDI_LISTENER_FACTORY_EXTENDED_CLASS );
|
||||
}
|
||||
|
||||
private static ListenerFactory buildStandardBeanManagerListenerFactory(Object beanManagerRef) {
|
||||
return buildBeanManagerListenerFactory( beanManagerRef, CDI_LISTENER_FACTORY_STANDARD_CLASS );
|
||||
}
|
||||
|
||||
private static ListenerFactory buildDelayedBeanManagerListenerFactory(Object beanManagerRef) {
|
||||
return buildBeanManagerListenerFactory( beanManagerRef, CDI_LISTENER_FACTORY_DELAYED_CLASS );
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static ListenerFactory buildBeanManagerListenerFactory(
|
||||
Object beanManagerRef,
|
||||
String listenerClass) {
|
||||
try {
|
||||
// specifically using our ClassLoader here...
|
||||
final Class beanManagerListenerFactoryClass = ListenerFactoryBuilder.class.getClassLoader()
|
||||
.loadClass( listenerClass );
|
||||
final Method beanManagerListenerFactoryBuilderMethod = beanManagerListenerFactoryClass.getMethod(
|
||||
CDI_LISTENER_FACTORY_METHOD_NAME,
|
||||
Object.class
|
||||
);
|
||||
|
||||
try {
|
||||
return (ListenerFactory) beanManagerListenerFactoryBuilderMethod.invoke( null, beanManagerRef );
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
throw e.getTargetException();
|
||||
}
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw new HibernateException(
|
||||
"Could not locate BeanManager ListenerFactory class [" + listenerClass + "] to handle CDI extensions",
|
||||
e
|
||||
);
|
||||
}
|
||||
catch (HibernateException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new HibernateException(
|
||||
"Could not access BeanManager ListenerFactory class [" + listenerClass + "] to handle CDI extensions",
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.jpa.event.spi.jpa;
|
||||
|
||||
/**
|
||||
* SPI classes for integrating with JPA event callbacks
|
||||
*/
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.resource.beans.internal;
|
||||
|
||||
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.jboss.logging.annotations.LogMessage;
|
||||
import org.jboss.logging.annotations.Message;
|
||||
import org.jboss.logging.annotations.MessageLogger;
|
||||
import org.jboss.logging.annotations.ValidIdRange;
|
||||
|
||||
import static org.jboss.logging.Logger.Level.INFO;
|
||||
import static org.jboss.logging.Logger.Level.WARN;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@MessageLogger( projectCode = "HHH" )
|
||||
@ValidIdRange( min = 10005001, max = 10010000 )
|
||||
public interface BeansMessageLogger {
|
||||
/**
|
||||
* *The* BeansMessageLogger instance
|
||||
*/
|
||||
BeansMessageLogger CDI_LOGGER = Logger.getMessageLogger(
|
||||
BeansMessageLogger.class,
|
||||
"org.hibernate.orm.beans"
|
||||
);
|
||||
|
||||
@LogMessage( level = WARN )
|
||||
@Message(
|
||||
id = 10005001,
|
||||
value = "An explicit CDI BeanManager reference [%s] was passed to Hibernate, " +
|
||||
"but CDI is not available on the Hibernate ClassLoader. This is likely " +
|
||||
"going to lead to exceptions later on in bootstrap"
|
||||
)
|
||||
void beanManagerButCdiNotAvailable(Object cdiBeanManagerReference);
|
||||
|
||||
@LogMessage( level = INFO )
|
||||
@Message(
|
||||
id = 10005002,
|
||||
value = "No explicit CDI BeanManager reference was passed to Hibernate, " +
|
||||
"but CDI is available on the Hibernate ClassLoader."
|
||||
)
|
||||
void noBeanManagerButCdiAvailable();
|
||||
|
||||
@LogMessage( level = INFO )
|
||||
@Message(
|
||||
id = 10005003,
|
||||
value = "Stopping ManagedBeanRegistry : %s"
|
||||
)
|
||||
void stoppingManagedBeanRegistry(ManagedBeanRegistry registry);
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.resource.beans.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.hibernate.resource.beans.spi.ManagedBean;
|
||||
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
||||
|
||||
/**
|
||||
* A ManagedBeanRegistry implementation that can delegate to multiple
|
||||
* other ManagedBeanRegistry instances, until one can handle the given call.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class CompositeManagedBeanRegistry implements ManagedBeanRegistry {
|
||||
|
||||
private List<ManagedBeanRegistry> delegates;
|
||||
|
||||
public void addDelegate(ManagedBeanRegistry beanRegistry) {
|
||||
if ( delegates == null ) {
|
||||
delegates = new ArrayList<>();
|
||||
}
|
||||
|
||||
delegates.add( beanRegistry );
|
||||
}
|
||||
@Override
|
||||
public <T> ManagedBean<T> getBean(Class<T> beanClass) {
|
||||
return tryEachRegistry( registry -> registry.getBean( beanClass ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ManagedBean<T> getBean(String beanName, Class<T> contract) {
|
||||
return tryEachRegistry( registry -> registry.getBean( beanName, contract ) );
|
||||
}
|
||||
|
||||
private <T> ManagedBean<T> tryEachRegistry(Function<ManagedBeanRegistry, ManagedBean<T>> delegateAction) {
|
||||
if ( delegates != null ) {
|
||||
for ( ManagedBeanRegistry delegate : delegates ) {
|
||||
ManagedBean<T> bean = null;
|
||||
try {
|
||||
bean = delegateAction.apply( delegate );
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
}
|
||||
|
||||
if ( bean != null ) {
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return delegateAction.apply( ManagedBeanRegistryDirectImpl.INSTANCE );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.resource.beans.internal;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||
import org.hibernate.engine.config.spi.StandardConverters;
|
||||
import org.hibernate.jpa.AvailableSettings;
|
||||
import org.hibernate.resource.beans.spi.ExtendedBeanManager;
|
||||
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
||||
import org.hibernate.resource.beans.spi.ManagedBeanRegistryInitiator;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
|
||||
/**
|
||||
* Utility class for helping deal with the reflection calls relating to CDI.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ManagedBeanRegistryCdiBuilder {
|
||||
private static final String REGISTRY_FQN_STANDARD = "org.hibernate.resource.beans.internal.ManagedBeanRegistryCdiStandardImpl";
|
||||
private static final String REGISTRY_FQN_DELAYED = "org.hibernate.resource.beans.internal.ManagedBeanRegistryCdiDelayedImpl";
|
||||
private static final String REGISTRY_FQN_EXTENDED = "org.hibernate.resource.beans.internal.ManagedBeanRegistryCdiExtendedImpl";
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static ManagedBeanRegistry fromBeanManagerReference(
|
||||
Object beanManagerRef,
|
||||
ServiceRegistry serviceRegistry) {
|
||||
final ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
|
||||
final Class beanManagerClass = ManagedBeanRegistryInitiator.cdiBeanManagerClass( classLoaderService );
|
||||
|
||||
final Class<? extends ManagedBeanRegistry> registryClass;
|
||||
final Class ctorArgType;
|
||||
|
||||
if ( ExtendedBeanManager.class.isInstance( beanManagerRef ) ) {
|
||||
registryClass = getHibernateClass( REGISTRY_FQN_EXTENDED );
|
||||
ctorArgType = ExtendedBeanManager.class;
|
||||
}
|
||||
else {
|
||||
ctorArgType = beanManagerClass;
|
||||
|
||||
final ConfigurationService cfgService = serviceRegistry.getService( ConfigurationService.class );
|
||||
final boolean delayAccessToCdi = cfgService.getSetting( AvailableSettings.DELAY_CDI_ACCESS, StandardConverters.BOOLEAN, false );
|
||||
if ( delayAccessToCdi ) {
|
||||
registryClass = getHibernateClass( REGISTRY_FQN_DELAYED );
|
||||
}
|
||||
else {
|
||||
registryClass = getHibernateClass( REGISTRY_FQN_STANDARD );
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
final Constructor<? extends ManagedBeanRegistry> ctor = registryClass.getDeclaredConstructor( ctorArgType );
|
||||
try {
|
||||
ctor.setAccessible( true );
|
||||
return ctor.newInstance( ctorArgType.cast( beanManagerRef ) );
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
throw new HibernateException( "Problem building " + registryClass.getName(), e.getCause() );
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new HibernateException( "Problem building " + registryClass.getName(), e );
|
||||
}
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
throw new HibernateException(
|
||||
String.format(
|
||||
Locale.ENGLISH,
|
||||
"Could not locate proper %s constructor",
|
||||
registryClass.getName()
|
||||
),
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> Class<T> getHibernateClass(String fqn) {
|
||||
// we use this Class's ClassLoader...
|
||||
try {
|
||||
return (Class<T>) Class.forName(
|
||||
fqn,
|
||||
true,
|
||||
ManagedBeanRegistryCdiBuilder.class.getClassLoader()
|
||||
);
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw new HibernateException( "Unable to locate Hibernate class by name via reflection : " + fqn, e );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.resource.beans.internal;
|
||||
|
||||
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 org.hibernate.resource.beans.spi.AbstractManagedBeanRegistry;
|
||||
import org.hibernate.resource.beans.spi.ManagedBean;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* A CDI-based ManagedBeanRegistry for Hibernate delaying access to the
|
||||
* BeanManager until first need.
|
||||
*
|
||||
* @see ManagedBeanRegistryCdiExtendedImpl
|
||||
* @see ManagedBeanRegistryCdiStandardImpl
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ManagedBeanRegistryCdiDelayedImpl extends AbstractManagedBeanRegistry {
|
||||
private static final Logger log = Logger.getLogger( ManagedBeanRegistryCdiDelayedImpl.class );
|
||||
|
||||
private final BeanManager beanManager;
|
||||
|
||||
private ManagedBeanRegistryCdiDelayedImpl(BeanManager beanManager) {
|
||||
this.beanManager = beanManager;
|
||||
log.debugf( "Delayed access requested to CDI BeanManager : " + beanManager );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T> ManagedBean<T> createBean(String beanName, Class<T> beanContract) {
|
||||
return new ManagedBeanImpl<>( beanContract );
|
||||
}
|
||||
|
||||
private class ManagedBeanImpl<T> implements ManagedBean<T> {
|
||||
private final Class<T> beanClass;
|
||||
|
||||
private boolean initialized = false;
|
||||
|
||||
private InjectionTarget<T> injectionTarget;
|
||||
private CreationalContext<T> creationalContext;
|
||||
private T beanInstance;
|
||||
|
||||
public ManagedBeanImpl(Class<T> beanClass) {
|
||||
this.beanClass = beanClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<T> getBeanClass() {
|
||||
return beanClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getBeanInstance() {
|
||||
if ( !initialized ) {
|
||||
initialize();
|
||||
}
|
||||
return beanInstance;
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
log.debug( "Delayed initialization of CDI bean on first use : " + beanClass );
|
||||
|
||||
final AnnotatedType<T> annotatedType = beanManager.createAnnotatedType( beanClass );
|
||||
this.injectionTarget = beanManager.createInjectionTarget( annotatedType );
|
||||
this.creationalContext = beanManager.createCreationalContext( null );
|
||||
|
||||
this.beanInstance = injectionTarget.produce( creationalContext );
|
||||
injectionTarget.inject( this.beanInstance, creationalContext );
|
||||
|
||||
injectionTarget.postConstruct( this.beanInstance );
|
||||
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
if ( !initialized ) {
|
||||
log.debug( "Skipping release for delayed CDI bean [" + beanClass + "] as it was not initialized" );
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug( "Releasing CDI listener : " + beanClass );
|
||||
|
||||
injectionTarget.preDestroy( beanInstance );
|
||||
injectionTarget.dispose( beanInstance );
|
||||
creationalContext.release();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.resource.beans.internal;
|
||||
|
||||
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 org.hibernate.resource.beans.spi.AbstractManagedBeanRegistry;
|
||||
import org.hibernate.resource.beans.spi.ExtendedBeanManager;
|
||||
import org.hibernate.resource.beans.spi.ManagedBean;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* A CDI-based ManagedBeanRegistry for Hibernate leveraging a proposed extension to CDI.
|
||||
* Specifically the extension is meant to tell us when the CDI BeanManager is usable.
|
||||
* So it is a delayed strategy, but delayed until a specific event : namely when our
|
||||
* {@link ExtendedBeanManager.LifecycleListener} callbacks occur.
|
||||
*
|
||||
* @see ManagedBeanRegistryCdiStandardImpl
|
||||
* @see ManagedBeanRegistryCdiDelayedImpl
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ManagedBeanRegistryCdiExtendedImpl
|
||||
extends AbstractManagedBeanRegistry
|
||||
implements ExtendedBeanManager.LifecycleListener {
|
||||
|
||||
private static final Logger log = Logger.getLogger( ManagedBeanRegistryCdiStandardImpl.class );
|
||||
|
||||
private BeanManager usableBeanManager;
|
||||
|
||||
private ManagedBeanRegistryCdiExtendedImpl(ExtendedBeanManager beanManager) {
|
||||
beanManager.registerLifecycleListener( this );
|
||||
log.debugf( "Extended access requested to CDI BeanManager : " + beanManager );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T> ManagedBean<T> createBean(String beanName, Class<T> beanContract) {
|
||||
return new ManagedBeanImpl<>( beanContract );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beanManagerInitialized(BeanManager beanManager) {
|
||||
this.usableBeanManager = beanManager;
|
||||
|
||||
// force each bean to initialize
|
||||
forEachBean( ManagedBean::getBeanInstance );
|
||||
}
|
||||
|
||||
private BeanManager getUsableBeanManager() {
|
||||
if ( usableBeanManager == null ) {
|
||||
throw new IllegalStateException( "ExtendedBeanManager.LifecycleListener callback not yet called: CDI not (yet) usable" );
|
||||
}
|
||||
return usableBeanManager;
|
||||
}
|
||||
|
||||
private class ManagedBeanImpl<T> implements ManagedBean<T> {
|
||||
private final Class<T> beanClass;
|
||||
|
||||
private boolean initialized = false;
|
||||
|
||||
private InjectionTarget<T> injectionTarget;
|
||||
private CreationalContext<T> creationalContext;
|
||||
private T beanInstance;
|
||||
|
||||
private ManagedBeanImpl(Class<T> beanClass) {
|
||||
this.beanClass = beanClass;
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
final BeanManager beanManager = getUsableBeanManager();
|
||||
AnnotatedType<T> annotatedType = beanManager.createAnnotatedType( beanClass );
|
||||
this.injectionTarget = beanManager.createInjectionTarget( annotatedType );
|
||||
this.creationalContext = beanManager.createCreationalContext( null );
|
||||
|
||||
this.beanInstance = injectionTarget.produce( creationalContext );
|
||||
injectionTarget.inject( this.beanInstance, creationalContext );
|
||||
|
||||
injectionTarget.postConstruct( this.beanInstance );
|
||||
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<T> getBeanClass() {
|
||||
return beanClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getBeanInstance() {
|
||||
if ( !initialized ) {
|
||||
initialize();
|
||||
}
|
||||
return beanInstance;
|
||||
}
|
||||
|
||||
public void release() {
|
||||
if ( !initialized ) {
|
||||
// log
|
||||
return;
|
||||
}
|
||||
|
||||
injectionTarget.preDestroy( beanInstance );
|
||||
injectionTarget.dispose( beanInstance );
|
||||
creationalContext.release();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.resource.beans.internal;
|
||||
|
||||
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 org.hibernate.resource.beans.spi.AbstractManagedBeanRegistry;
|
||||
import org.hibernate.resource.beans.spi.ManagedBean;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* A CDI-based ManagedBeanRegistry for Hibernate following the JPA standard
|
||||
* prescribed manner... namely assuming immediate access to the BeanManager is
|
||||
* allowed.
|
||||
*
|
||||
* @see ManagedBeanRegistryCdiExtendedImpl
|
||||
* @see ManagedBeanRegistryCdiDelayedImpl
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
class ManagedBeanRegistryCdiStandardImpl extends AbstractManagedBeanRegistry {
|
||||
private static final Logger log = Logger.getLogger( ManagedBeanRegistryCdiStandardImpl.class );
|
||||
|
||||
private final BeanManager beanManager;
|
||||
|
||||
private ManagedBeanRegistryCdiStandardImpl(BeanManager beanManager) {
|
||||
this.beanManager = beanManager;
|
||||
log.debugf( "Standard access requested to CDI BeanManager : " + beanManager );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T> ManagedBean<T> createBean(String beanName, Class<T> beanContract) {
|
||||
return new ManagedBeanImpl<>( beanContract );
|
||||
}
|
||||
|
||||
private class ManagedBeanImpl<T> implements ManagedBean<T> {
|
||||
private final Class<T> beanClass;
|
||||
private final InjectionTarget<T> injectionTarget;
|
||||
private final CreationalContext<T> creationalContext;
|
||||
private final T beanInstance;
|
||||
|
||||
public ManagedBeanImpl(Class<T> beanClass) {
|
||||
this.beanClass = beanClass;
|
||||
|
||||
AnnotatedType<T> annotatedType = beanManager.createAnnotatedType( beanClass );
|
||||
this.injectionTarget = beanManager.createInjectionTarget( annotatedType );
|
||||
this.creationalContext = beanManager.createCreationalContext( null );
|
||||
|
||||
this.beanInstance = injectionTarget.produce( creationalContext );
|
||||
injectionTarget.inject( this.beanInstance, creationalContext );
|
||||
|
||||
injectionTarget.postConstruct( this.beanInstance );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<T> getBeanClass() {
|
||||
return beanClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getBeanInstance() {
|
||||
return beanInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
injectionTarget.preDestroy( beanInstance );
|
||||
injectionTarget.dispose( beanInstance );
|
||||
creationalContext.release();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.resource.beans.internal;
|
||||
|
||||
import org.hibernate.InstantiationException;
|
||||
import org.hibernate.resource.beans.spi.AbstractManagedBeanRegistry;
|
||||
import org.hibernate.resource.beans.spi.ManagedBean;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* ManagedBeanRegistry implementation using direct instantiation of the beans. Used
|
||||
* when there is no backing "injection framework" in use as well as the fallback
|
||||
* for {@link CompositeManagedBeanRegistry}
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ManagedBeanRegistryDirectImpl extends AbstractManagedBeanRegistry {
|
||||
|
||||
private static final Logger log = Logger.getLogger( ManagedBeanRegistryDirectImpl.class );
|
||||
|
||||
/**
|
||||
* Singleton access
|
||||
*/
|
||||
public static final ManagedBeanRegistryDirectImpl INSTANCE = new ManagedBeanRegistryDirectImpl();
|
||||
|
||||
private ManagedBeanRegistryDirectImpl() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T> ManagedBean<T> createBean(String beanName, Class<T> beanContract) {
|
||||
return new ManagedBeanImpl<>( beanContract );
|
||||
}
|
||||
|
||||
private class ManagedBeanImpl<T> implements ManagedBean<T> {
|
||||
private final Class<T> beanClass;
|
||||
private final T bean;
|
||||
|
||||
private ManagedBeanImpl(Class<T> beanClass) {
|
||||
log.debugf( "Creating ManagedBean[%s] using direct instantiation", beanClass.getName() );
|
||||
this.beanClass = beanClass;
|
||||
try {
|
||||
this.bean = beanClass.newInstance();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new InstantiationException( "Could not instantiate managed bean directly", beanClass, e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<T> getBeanClass() {
|
||||
return beanClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getBeanInstance() {
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Defines Hibernate's integration with CDI. Because CDI may or may not be available
|
||||
* a lot of this support is directed toward abstracting/encapsulating CDI. The
|
||||
* central contracts here from a consumption point-of-view are
|
||||
* {@link org.hibernate.resource.beans.spi.ManagedBean} and
|
||||
* {@link org.hibernate.resource.beans.spi.ManagedBeanRegistry} which may or may not
|
||||
* really be backed by CDI.
|
||||
*/
|
||||
package org.hibernate.resource.beans;
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.resource.beans.spi;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.resource.beans.internal.BeansMessageLogger;
|
||||
import org.hibernate.service.spi.Stoppable;
|
||||
|
||||
/**
|
||||
* Abstract support (template pattern) for ManagedBeanRegistry implementations
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractManagedBeanRegistry implements ManagedBeanRegistry, Stoppable {
|
||||
private Map<String,ManagedBean<?>> registrations = new HashMap<>();
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> ManagedBean<T> getBean(String beanName, Class<T> beanContract) {
|
||||
final ManagedBean<T> existing = (ManagedBean<T>) registrations.get( beanName );
|
||||
if ( existing != null ) {
|
||||
return existing;
|
||||
}
|
||||
|
||||
final ManagedBean<T> bean = createBean( beanName, beanContract );
|
||||
registrations.put( beanName, bean );
|
||||
return bean;
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected abstract <T> ManagedBean<T> createBean(String beanName, Class<T> beanContract);
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected void forEachBean(Consumer<ManagedBean<?>> consumer) {
|
||||
registrations.values().forEach( consumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
BeansMessageLogger.CDI_LOGGER.stoppingManagedBeanRegistry( this );
|
||||
forEachBean( ManagedBean::release );
|
||||
registrations.clear();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.resource.beans.spi;
|
||||
|
||||
import javax.enterprise.inject.spi.BeanManager;
|
||||
|
||||
/**
|
||||
* This contract and the nested LifecycleListener contract represent the changes
|
||||
* we'd like to propose to the CDI spec. The idea being simply to allow contextual
|
||||
* registration of BeanManager lifecycle callbacks
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ExtendedBeanManager {
|
||||
/**
|
||||
* Register a BeanManager LifecycleListener
|
||||
*
|
||||
* @param lifecycleListener The listener to register
|
||||
*/
|
||||
void registerLifecycleListener(LifecycleListener lifecycleListener);
|
||||
|
||||
/**
|
||||
* Contract for things interested in receiving notifications of
|
||||
* BeanManager lifecycle events.
|
||||
* <p/>
|
||||
* A "beanManagerDestroyed" notifications would probably also be generally
|
||||
* useful, although we do not need it here and not sure WildFly can really
|
||||
* tell us that reliably.
|
||||
*/
|
||||
interface LifecycleListener {
|
||||
void beanManagerInitialized(BeanManager beanManager);
|
||||
}
|
||||
}
|
|
@ -4,14 +4,15 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.jpa.event.spi.jpa;
|
||||
package org.hibernate.resource.beans.spi;
|
||||
|
||||
/**
|
||||
* Encapsulates access to the listener instance for listener callbacks
|
||||
* ({@link javax.persistence.EntityListeners}).
|
||||
* Generalized contract for a CDI ManagedBean as seen by Hibernate
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface Listener<T> {
|
||||
T getListener();
|
||||
}
|
||||
public interface ManagedBean<T> {
|
||||
Class<T> getBeanClass();
|
||||
T getBeanInstance();
|
||||
void release();
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.resource.beans.spi;
|
||||
|
||||
import org.hibernate.service.Service;
|
||||
|
||||
/**
|
||||
* A registry for ManagedBean instances. Responsible for managing the lifecycle.
|
||||
* <p/>
|
||||
* Access to the beans and usage of them are only valid between the time
|
||||
* the registry is initialized and released (however those events are recognized).
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ManagedBeanRegistry extends Service {
|
||||
/**
|
||||
* Get a bean reference, by class. By default, calls
|
||||
* {@link #getBean(String, Class)} using the beanClass's name
|
||||
*/
|
||||
default <T> ManagedBean<T> getBean(Class<T> beanClass) {
|
||||
return getBean( beanClass.getName(), beanClass );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a bean reference by name, typed as the given bean contract.
|
||||
*/
|
||||
<T> ManagedBean<T> getBean(String beanName, Class<T> contract);
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.resource.beans.spi;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.boot.registry.StandardServiceInitiator;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||
import org.hibernate.resource.beans.internal.BeansMessageLogger;
|
||||
import org.hibernate.resource.beans.internal.CompositeManagedBeanRegistry;
|
||||
import org.hibernate.resource.beans.internal.ManagedBeanRegistryCdiBuilder;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
|
||||
/**
|
||||
* Hibernate's standard initializer for the ManagedBeanRegistry service.
|
||||
*
|
||||
* Produces a {@link CompositeManagedBeanRegistry}
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ManagedBeanRegistryInitiator implements StandardServiceInitiator<ManagedBeanRegistry> {
|
||||
/**
|
||||
* Singleton access
|
||||
*/
|
||||
public static final ManagedBeanRegistryInitiator INSTANCE = new ManagedBeanRegistryInitiator();
|
||||
|
||||
@Override
|
||||
public Class<ManagedBeanRegistry> getServiceInitiated() {
|
||||
return ManagedBeanRegistry.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManagedBeanRegistry initiateService(
|
||||
Map configurationValues,
|
||||
ServiceRegistryImplementor serviceRegistry) {
|
||||
final ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
|
||||
final ConfigurationService cfgSvc = serviceRegistry.getService( ConfigurationService.class );
|
||||
|
||||
final CompositeManagedBeanRegistry beanRegistry = new CompositeManagedBeanRegistry();
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// apply CDI support
|
||||
|
||||
final boolean isCdiAvailable = isCdiAvailable( classLoaderService );
|
||||
final Object beanManagerRef = cfgSvc.getSettings().get( AvailableSettings.CDI_BEAN_MANAGER );
|
||||
if ( beanManagerRef != null ) {
|
||||
if ( !isCdiAvailable ) {
|
||||
BeansMessageLogger.CDI_LOGGER.beanManagerButCdiNotAvailable( beanManagerRef );
|
||||
}
|
||||
|
||||
beanRegistry.addDelegate(
|
||||
ManagedBeanRegistryCdiBuilder.fromBeanManagerReference( beanManagerRef, serviceRegistry )
|
||||
);
|
||||
}
|
||||
|
||||
return beanRegistry;
|
||||
}
|
||||
|
||||
private static boolean isCdiAvailable(ClassLoaderService classLoaderService) {
|
||||
// is CDI available on our ClassLoader?
|
||||
try {
|
||||
cdiBeanManagerClass( classLoaderService );
|
||||
return true;
|
||||
}
|
||||
catch (ClassLoadingException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static Class cdiBeanManagerClass(ClassLoaderService classLoaderService) throws ClassLoadingException {
|
||||
return classLoaderService.classForName( "javax.enterprise.inject.spi.BeanManager" );
|
||||
}
|
||||
|
||||
}
|
|
@ -31,6 +31,7 @@ import org.hibernate.jmx.internal.JmxServiceInitiator;
|
|||
import org.hibernate.persister.internal.PersisterClassResolverInitiator;
|
||||
import org.hibernate.persister.internal.PersisterFactoryInitiator;
|
||||
import org.hibernate.property.access.internal.PropertyAccessStrategyResolverInitiator;
|
||||
import org.hibernate.resource.beans.spi.ManagedBeanRegistryInitiator;
|
||||
import org.hibernate.resource.transaction.internal.TransactionCoordinatorBuilderInitiator;
|
||||
import org.hibernate.service.internal.SessionFactoryServiceRegistryFactoryInitiator;
|
||||
import org.hibernate.tool.hbm2ddl.ImportSqlCommandExtractorInitiator;
|
||||
|
@ -84,6 +85,8 @@ public final class StandardServiceInitiators {
|
|||
|
||||
serviceInitiators.add( TransactionCoordinatorBuilderInitiator.INSTANCE );
|
||||
|
||||
serviceInitiators.add( ManagedBeanRegistryInitiator.INSTANCE );
|
||||
|
||||
return Collections.unmodifiableList( serviceInitiators );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ public class ConversationalPersistenceContextExtendedTest {
|
|||
|
||||
private static PersistenceDescriptor persistenceXml() {
|
||||
return Descriptors.create( PersistenceDescriptor.class )
|
||||
.createPersistenceUnit().name( "pu-cdi-basic" )
|
||||
.createPersistenceUnit().name( "pu-beans-basic" )
|
||||
.clazz( Event.class.getName() )
|
||||
.excludeUnlistedClasses( true )
|
||||
.nonJtaDataSource( "java:jboss/datasources/ExampleDS" )
|
||||
|
|
|
@ -45,7 +45,7 @@ public class ManualFlushConversationalPersistenceContextExtendedTest {
|
|||
|
||||
private static PersistenceDescriptor persistenceXml() {
|
||||
return Descriptors.create( PersistenceDescriptor.class )
|
||||
.createPersistenceUnit().name( "pu-cdi-basic" )
|
||||
.createPersistenceUnit().name( "pu-beans-basic" )
|
||||
.clazz( Event.class.getName() )
|
||||
.excludeUnlistedClasses( true )
|
||||
.nonJtaDataSource( "java:jboss/datasources/ExampleDS" )
|
||||
|
|
|
@ -44,7 +44,7 @@ public class NonConversationalPersistenceContextExtendedTest {
|
|||
|
||||
private static PersistenceDescriptor persistenceXml() {
|
||||
return Descriptors.create( PersistenceDescriptor.class )
|
||||
.createPersistenceUnit().name( "pu-cdi-basic" )
|
||||
.createPersistenceUnit().name( "pu-beans-basic" )
|
||||
.clazz( Event.class.getName() )
|
||||
.excludeUnlistedClasses( true )
|
||||
.nonJtaDataSource( "java:jboss/datasources/ExampleDS" )
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Package for testing Hibernate's support for integrating
|
||||
* with CDI for JPA attribute converters
|
||||
*/
|
||||
package org.hibernate.test.cdi.converters;
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.test.cdi.events;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class Monitor {
|
||||
private static final AtomicInteger count = new AtomicInteger( 0 );
|
||||
private static boolean instantiated;
|
||||
|
||||
public Monitor() {
|
||||
instantiated = true;
|
||||
}
|
||||
|
||||
public static void reset() {
|
||||
instantiated = false;
|
||||
count.set( 0 );
|
||||
}
|
||||
|
||||
public static boolean wasInstantiated() {
|
||||
return instantiated;
|
||||
}
|
||||
|
||||
public static int currentCount() {
|
||||
return count.get();
|
||||
}
|
||||
|
||||
public void entitySaved() {
|
||||
count.getAndIncrement();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.test.cdi.events;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityListeners;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Entity
|
||||
@Table( name = "the_entity")
|
||||
@EntityListeners( TheListener.class )
|
||||
public class TheEntity {
|
||||
private Integer id;
|
||||
private String name;
|
||||
|
||||
public TheEntity() {
|
||||
}
|
||||
|
||||
public TheEntity(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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.test.cdi.events;
|
||||
|
||||
import javax.persistence.PrePersist;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class TheListener {
|
||||
private final Monitor monitor;
|
||||
|
||||
@javax.inject.Inject
|
||||
public TheListener(Monitor monitor) {
|
||||
this.monitor = monitor;
|
||||
}
|
||||
|
||||
@PrePersist
|
||||
public void onCreate(Object entity) {
|
||||
monitor.entitySaved();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.test.cdi.events.delayed;
|
||||
|
||||
import javax.enterprise.inject.se.SeContainer;
|
||||
import javax.enterprise.inject.se.SeContainerInitializer;
|
||||
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.registry.BootstrapServiceRegistry;
|
||||
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.jpa.event.spi.JpaIntegrator;
|
||||
import org.hibernate.tool.schema.Action;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
import org.hibernate.test.cdi.events.Monitor;
|
||||
import org.hibernate.test.cdi.events.TheEntity;
|
||||
import org.hibernate.test.cdi.events.TheListener;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil2.inTransaction;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests support for CDI delaying access to the CDI container until
|
||||
* first needed
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DelayedCdiSupportTest extends BaseUnitTestCase {
|
||||
@Test
|
||||
public void testIt() {
|
||||
Monitor.reset();
|
||||
|
||||
final SeContainerInitializer cdiInitializer = SeContainerInitializer.newInstance()
|
||||
.disableDiscovery()
|
||||
.addBeanClasses( Monitor.class, TheListener.class );
|
||||
try ( final SeContainer cdiContainer = cdiInitializer.initialize() ) {
|
||||
BootstrapServiceRegistry bsr = new BootstrapServiceRegistryBuilder()
|
||||
.applyIntegrator( new JpaIntegrator() )
|
||||
.build();
|
||||
|
||||
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder( bsr )
|
||||
.applySetting( AvailableSettings.HBM2DDL_AUTO, Action.CREATE_DROP )
|
||||
.applySetting( AvailableSettings.CDI_BEAN_MANAGER, cdiContainer.getBeanManager() )
|
||||
.applySetting( AvailableSettings.DELAY_CDI_ACCESS, "true" )
|
||||
.build();
|
||||
|
||||
final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
try {
|
||||
sessionFactory = (SessionFactoryImplementor) new MetadataSources( ssr )
|
||||
.addAnnotatedClass( TheEntity.class )
|
||||
.buildMetadata()
|
||||
.getSessionFactoryBuilder()
|
||||
.build();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
StandardServiceRegistryBuilder.destroy( ssr );
|
||||
throw e;
|
||||
}
|
||||
|
||||
// The CDI bean should not be built immediately...
|
||||
assertFalse( Monitor.wasInstantiated() );
|
||||
assertEquals( 0, Monitor.currentCount() );
|
||||
|
||||
try {
|
||||
inTransaction(
|
||||
sessionFactory,
|
||||
session -> session.persist( new TheEntity( 1 ) )
|
||||
);
|
||||
|
||||
// The CDI bean should have been built on first use
|
||||
assertTrue( Monitor.wasInstantiated() );
|
||||
assertEquals( 1, Monitor.currentCount() );
|
||||
|
||||
inTransaction(
|
||||
sessionFactory,
|
||||
session -> {
|
||||
TheEntity it = session.find( TheEntity.class, 1 );
|
||||
assertNotNull( it );
|
||||
}
|
||||
);
|
||||
}
|
||||
finally {
|
||||
inTransaction(
|
||||
sessionFactory,
|
||||
session -> {
|
||||
session.createQuery( "delete TheEntity" ).executeUpdate();
|
||||
}
|
||||
);
|
||||
|
||||
sessionFactory.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.test.cdi.events.extended;
|
||||
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.registry.BootstrapServiceRegistry;
|
||||
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.jpa.event.spi.JpaIntegrator;
|
||||
import org.hibernate.resource.beans.spi.ExtendedBeanManager;
|
||||
import org.hibernate.tool.schema.Action;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
import org.hibernate.test.cdi.events.Monitor;
|
||||
import org.hibernate.test.cdi.events.TheEntity;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil2.inTransaction;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* Tests support for CDI delaying access to the CDI container until
|
||||
* first needed
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class InvalidExtendedCdiSupportTest extends BaseUnitTestCase {
|
||||
@Test
|
||||
public void testIt() {
|
||||
Monitor.reset();
|
||||
|
||||
|
||||
final ExtendedBeanManagerImpl standIn = new ExtendedBeanManagerImpl();
|
||||
|
||||
BootstrapServiceRegistry bsr = new BootstrapServiceRegistryBuilder()
|
||||
.applyIntegrator( new JpaIntegrator() )
|
||||
.build();
|
||||
|
||||
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder( bsr )
|
||||
.applySetting( AvailableSettings.HBM2DDL_AUTO, Action.CREATE_DROP )
|
||||
.applySetting( AvailableSettings.CDI_BEAN_MANAGER, standIn )
|
||||
.build();
|
||||
|
||||
|
||||
final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
try {
|
||||
sessionFactory = (SessionFactoryImplementor) new MetadataSources( ssr )
|
||||
.addAnnotatedClass( TheEntity.class )
|
||||
.buildMetadata()
|
||||
.getSessionFactoryBuilder()
|
||||
.build();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
StandardServiceRegistryBuilder.destroy( ssr );
|
||||
throw e;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
// The CDI bean should not be built immediately...
|
||||
assertFalse( Monitor.wasInstantiated() );
|
||||
assertEquals( 0, Monitor.currentCount() );
|
||||
|
||||
// this time (compared to the valid test) lets not build the CDI
|
||||
// container and just let Hibernate try to use the uninitialized
|
||||
// ExtendedBeanManager reference
|
||||
|
||||
try {
|
||||
inTransaction(
|
||||
sessionFactory,
|
||||
session -> session.persist( new TheEntity( 1 ) )
|
||||
);
|
||||
|
||||
inTransaction(
|
||||
sessionFactory,
|
||||
session -> {
|
||||
session.createQuery( "delete TheEntity" ).executeUpdate();
|
||||
}
|
||||
);
|
||||
|
||||
fail( "Expecting failure" );
|
||||
}
|
||||
catch (IllegalStateException expected) {
|
||||
}
|
||||
}
|
||||
finally {
|
||||
sessionFactory.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExtendedBeanManagerImpl implements ExtendedBeanManager {
|
||||
@Override
|
||||
public void registerLifecycleListener(LifecycleListener lifecycleListener) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.test.cdi.events.extended;
|
||||
|
||||
import javax.enterprise.inject.se.SeContainer;
|
||||
import javax.enterprise.inject.se.SeContainerInitializer;
|
||||
import javax.enterprise.inject.spi.BeanManager;
|
||||
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.registry.BootstrapServiceRegistry;
|
||||
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.jpa.event.spi.JpaIntegrator;
|
||||
import org.hibernate.resource.beans.spi.ExtendedBeanManager;
|
||||
import org.hibernate.tool.schema.Action;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
import org.hibernate.test.cdi.events.Monitor;
|
||||
import org.hibernate.test.cdi.events.TheEntity;
|
||||
import org.hibernate.test.cdi.events.TheListener;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil2.inTransaction;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests support for CDI delaying access to the CDI container until
|
||||
* first needed
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ValidExtendedCdiSupportTest extends BaseUnitTestCase {
|
||||
@Test
|
||||
public void testIt() {
|
||||
Monitor.reset();
|
||||
|
||||
|
||||
final ExtendedBeanManagerImpl standIn = new ExtendedBeanManagerImpl();
|
||||
|
||||
BootstrapServiceRegistry bsr = new BootstrapServiceRegistryBuilder()
|
||||
.applyIntegrator( new JpaIntegrator() )
|
||||
.build();
|
||||
|
||||
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder( bsr )
|
||||
.applySetting( AvailableSettings.HBM2DDL_AUTO, Action.CREATE_DROP )
|
||||
.applySetting( AvailableSettings.CDI_BEAN_MANAGER, standIn )
|
||||
.build();
|
||||
|
||||
|
||||
final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
try {
|
||||
sessionFactory = (SessionFactoryImplementor) new MetadataSources( ssr )
|
||||
.addAnnotatedClass( TheEntity.class )
|
||||
.buildMetadata()
|
||||
.getSessionFactoryBuilder()
|
||||
.build();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
StandardServiceRegistryBuilder.destroy( ssr );
|
||||
throw e;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
// The CDI bean should not be built immediately...
|
||||
assertFalse( Monitor.wasInstantiated() );
|
||||
assertEquals( 0, Monitor.currentCount() );
|
||||
|
||||
|
||||
// But now lets initialize CDI and do the callback
|
||||
|
||||
final SeContainerInitializer cdiInitializer = SeContainerInitializer.newInstance()
|
||||
.disableDiscovery()
|
||||
.addBeanClasses( Monitor.class, TheListener.class );
|
||||
try (final SeContainer cdiContainer = cdiInitializer.initialize()) {
|
||||
|
||||
standIn.beanManagerReady( cdiContainer.getBeanManager() );
|
||||
|
||||
// at this point the bean should have been accessed
|
||||
assertTrue( Monitor.wasInstantiated() );
|
||||
assertEquals( 0, Monitor.currentCount() );
|
||||
|
||||
try {
|
||||
inTransaction(
|
||||
sessionFactory,
|
||||
session -> session.persist( new TheEntity( 1 ) )
|
||||
);
|
||||
|
||||
inTransaction(
|
||||
sessionFactory,
|
||||
session -> {
|
||||
TheEntity it = session.find( TheEntity.class, 1 );
|
||||
assertNotNull( it );
|
||||
}
|
||||
);
|
||||
}
|
||||
finally {
|
||||
inTransaction(
|
||||
sessionFactory,
|
||||
session -> {
|
||||
session.createQuery( "delete TheEntity" ).executeUpdate();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
sessionFactory.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExtendedBeanManagerImpl implements ExtendedBeanManager {
|
||||
private LifecycleListener callback;
|
||||
|
||||
@Override
|
||||
public void registerLifecycleListener(LifecycleListener lifecycleListener) {
|
||||
this.callback = lifecycleListener;
|
||||
}
|
||||
|
||||
public void beanManagerReady(BeanManager beanManager) {
|
||||
callback.beanManagerInitialized( beanManager );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.test.cdi.events.nocdi;
|
||||
|
||||
import org.hibernate.InstantiationException;
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.registry.BootstrapServiceRegistry;
|
||||
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.jpa.event.spi.JpaIntegrator;
|
||||
import org.hibernate.tool.schema.Action;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
import org.hibernate.test.cdi.events.Monitor;
|
||||
import org.hibernate.test.cdi.events.TheEntity;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* Attempt to use CDI injection when no CDI is available
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class InvalidNoCdiSupportTest extends BaseUnitTestCase {
|
||||
@Test
|
||||
public void testIt() {
|
||||
Monitor.reset();
|
||||
|
||||
BootstrapServiceRegistry bsr = new BootstrapServiceRegistryBuilder()
|
||||
.applyIntegrator( new JpaIntegrator() )
|
||||
.build();
|
||||
|
||||
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder( bsr )
|
||||
.applySetting( AvailableSettings.HBM2DDL_AUTO, Action.CREATE_DROP )
|
||||
.build();
|
||||
|
||||
final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
try {
|
||||
// because there is no CDI available, building the SF should immediately
|
||||
// try to build the ManagedBeans which should fail here
|
||||
sessionFactory = (SessionFactoryImplementor) new MetadataSources( ssr )
|
||||
.addAnnotatedClass( TheEntity.class )
|
||||
.buildMetadata()
|
||||
.getSessionFactoryBuilder()
|
||||
.build();
|
||||
sessionFactory.close();
|
||||
fail( "Expecting failure" );
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
StandardServiceRegistryBuilder.destroy( ssr );
|
||||
assertThat( e, instanceOf( InstantiationException.class ) );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.test.cdi.events.nocdi;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityListeners;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.PrePersist;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.registry.BootstrapServiceRegistry;
|
||||
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.jpa.event.spi.JpaIntegrator;
|
||||
import org.hibernate.tool.schema.Action;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
import org.hibernate.test.cdi.events.Monitor;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil2.inTransaction;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests valid use of ManagedBeanRegistry when CDI is not available -
|
||||
* meaning injection is not requested.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ValidNoCdiSupportTest extends BaseUnitTestCase {
|
||||
@Test
|
||||
public void testIt() {
|
||||
AnotherListener.reset();
|
||||
|
||||
BootstrapServiceRegistry bsr = new BootstrapServiceRegistryBuilder()
|
||||
.applyIntegrator( new JpaIntegrator() )
|
||||
.build();
|
||||
|
||||
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder( bsr )
|
||||
.applySetting( AvailableSettings.HBM2DDL_AUTO, Action.CREATE_DROP )
|
||||
.build();
|
||||
|
||||
final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
try {
|
||||
sessionFactory = (SessionFactoryImplementor) new MetadataSources( ssr )
|
||||
.addAnnotatedClass( AnotherEntity.class )
|
||||
.buildMetadata()
|
||||
.getSessionFactoryBuilder()
|
||||
.build();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
StandardServiceRegistryBuilder.destroy( ssr );
|
||||
throw e;
|
||||
}
|
||||
|
||||
// The CDI bean should have been built immediately...
|
||||
assertTrue( AnotherListener.wasInstantiated() );
|
||||
assertEquals( 0, AnotherListener.currentCount() );
|
||||
|
||||
try {
|
||||
inTransaction(
|
||||
sessionFactory,
|
||||
session -> session.persist( new AnotherEntity( 1 ) )
|
||||
);
|
||||
|
||||
assertEquals( 1, AnotherListener.currentCount() );
|
||||
|
||||
inTransaction(
|
||||
sessionFactory,
|
||||
session -> {
|
||||
AnotherEntity it = session.find( AnotherEntity.class, 1 );
|
||||
assertNotNull( it );
|
||||
}
|
||||
);
|
||||
}
|
||||
finally {
|
||||
inTransaction(
|
||||
sessionFactory,
|
||||
session -> {
|
||||
session.createQuery( "delete AnotherEntity" ).executeUpdate();
|
||||
}
|
||||
);
|
||||
|
||||
sessionFactory.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Entity( name = "AnotherEntity" )
|
||||
@Table( name = "another_entity")
|
||||
@EntityListeners( AnotherListener.class )
|
||||
public static class AnotherEntity {
|
||||
private Integer id;
|
||||
private String name;
|
||||
|
||||
public AnotherEntity() {
|
||||
}
|
||||
|
||||
public AnotherEntity(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 AnotherListener {
|
||||
private static final AtomicInteger count = new AtomicInteger( 0 );
|
||||
private static boolean instantiated;
|
||||
|
||||
public AnotherListener() {
|
||||
instantiated = true;
|
||||
}
|
||||
|
||||
public static void reset() {
|
||||
count.set( 0 );
|
||||
instantiated = false;
|
||||
}
|
||||
|
||||
public static boolean wasInstantiated() {
|
||||
return instantiated;
|
||||
}
|
||||
|
||||
public static int currentCount() {
|
||||
return count.get();
|
||||
}
|
||||
|
||||
@PrePersist
|
||||
public void onCreate(Object entity) {
|
||||
count.getAndIncrement();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Package for testing Hibernate's support for integrating
|
||||
* with CDI for JPA event listeners
|
||||
*/
|
||||
package org.hibernate.test.cdi.events;
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.test.cdi.events.standard;
|
||||
|
||||
import javax.enterprise.inject.se.SeContainer;
|
||||
import javax.enterprise.inject.se.SeContainerInitializer;
|
||||
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.registry.BootstrapServiceRegistry;
|
||||
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.jpa.event.spi.JpaIntegrator;
|
||||
import org.hibernate.tool.schema.Action;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
import org.hibernate.test.cdi.events.Monitor;
|
||||
import org.hibernate.test.cdi.events.TheEntity;
|
||||
import org.hibernate.test.cdi.events.TheListener;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil2.inTransaction;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests support for CDI as (implicitly) defined by JPA in terms of
|
||||
* immediate availability
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class StandardCdiSupportTest extends BaseUnitTestCase {
|
||||
@Test
|
||||
public void testIt() {
|
||||
Monitor.reset();
|
||||
|
||||
final SeContainerInitializer cdiInitializer = SeContainerInitializer.newInstance()
|
||||
.disableDiscovery()
|
||||
.addBeanClasses( Monitor.class, TheListener.class );
|
||||
try ( final SeContainer cdiContainer = cdiInitializer.initialize() ) {
|
||||
BootstrapServiceRegistry bsr = new BootstrapServiceRegistryBuilder()
|
||||
.applyIntegrator( new JpaIntegrator() )
|
||||
.build();
|
||||
|
||||
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder( bsr )
|
||||
.applySetting( AvailableSettings.HBM2DDL_AUTO, Action.CREATE_DROP )
|
||||
.applySetting( AvailableSettings.CDI_BEAN_MANAGER, cdiContainer.getBeanManager() )
|
||||
.build();
|
||||
|
||||
final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
try {
|
||||
sessionFactory = (SessionFactoryImplementor) new MetadataSources( ssr )
|
||||
.addAnnotatedClass( TheEntity.class )
|
||||
.buildMetadata()
|
||||
.getSessionFactoryBuilder()
|
||||
.build();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
StandardServiceRegistryBuilder.destroy( ssr );
|
||||
throw e;
|
||||
}
|
||||
|
||||
// The CDI bean should have been built immediately...
|
||||
assertTrue( Monitor.wasInstantiated() );
|
||||
assertEquals( 0, Monitor.currentCount() );
|
||||
|
||||
try {
|
||||
inTransaction(
|
||||
sessionFactory,
|
||||
session -> session.persist( new TheEntity( 1 ) )
|
||||
);
|
||||
|
||||
assertEquals( 1, Monitor.currentCount() );
|
||||
|
||||
inTransaction(
|
||||
sessionFactory,
|
||||
session -> {
|
||||
TheEntity it = session.find( TheEntity.class, 1 );
|
||||
assertNotNull( it );
|
||||
}
|
||||
);
|
||||
}
|
||||
finally {
|
||||
inTransaction(
|
||||
sessionFactory,
|
||||
session -> {
|
||||
session.createQuery( "delete TheEntity" ).executeUpdate();
|
||||
}
|
||||
);
|
||||
|
||||
sessionFactory.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base package for testing Hibernate's CDI integration
|
||||
*/
|
||||
package org.hibernate.test.cdi;
|
Loading…
Reference in New Issue