use of jakarta.enterprise.inject.CreationException in project helidon by oracle.
the class ExtendedEntityManager method acquireDelegate.
/*
* Instance methods.
*/
/**
* Acquires and returns the delegate {@link EntityManager} that
* this {@link ExtendedEntityManager} must use according to the
* rules for extended persistence contexts spelled out in the JPA
* specification.
*
* <p>This method never returns {@code null}.</p>
*
* @return the delegate {@link EntityManager}; never {@code null}
*/
@Override
@SuppressWarnings("checkstyle:MethodLength")
protected EntityManager acquireDelegate() {
// This is very tricky. Pay attention.
//
// An extended EntityManager's persistence context (its "bag"
// of "managed", not "detached", entities) spans transactions.
//
// In this CDI-centric implementation, we make use of
// jakarta.transaction.TransactionScoped to serve up
// EntityManager instances in true JTA transaction scope.
// That means those objects are destroyed when the transaction
// is destroyed. Obviously therefore they cannot be used as
// the sole basis for the transaction-respecting bits of an
// extended EntityManager.
//
// However, an extended EntityManager must "become" the sole
// EntityManager associated with a JTA transaction, and then
// must dissociate from it after it has committed or rolled
// back.
//
// So we make use of the fact that the @TransactionScoped bean
// that has been installed is going to produce instances of
// CdiTransactionScopedEntityManager. This
// DelegatingEntityManager subclass allows you to set _its_
// delegate, provided it has not yet been set, and allows you
// to control whether or not its delegate is actually closed
// when _it_ is closed. This lets us "tunnel" another
// EntityManager "into" transaction scope.
final EntityManager returnValue;
final Context context = transactionSupport.getContext();
if (context == null || !context.isActive()) {
if (this.delegate == null) {
assert this.subdelegate == null;
// For the first time during the lifespan of this
// object, create its delegate. It will be a "normal"
// EntityManager. We don't set our subdelegate
// because that is only set in transactional cases
// (see below).
this.delegate = EntityManagers.createContainerManagedEntityManager(this.instance, this.suppliedQualifiers);
} else if (this.delegate instanceof CdiTransactionScopedEntityManager) {
// (see later in this method for proof).
assert this.subdelegate != null;
assert !(this.subdelegate instanceof CdiTransactionScopedEntityManager);
assert this.subdelegate.isOpen();
// We are an extended EntityManager, so take that old
// "normal" EntityManager subdelegate that we know was
// "tunneled" into our "stale"
// CdiTransactionScopedEntityManager delegate, and
// "pull it out" to be our delegate. We can discard
// the stale CdiTransactionScopedEntityManager at this
// point, which we do by just overwriting its
// reference.
this.delegate = this.subdelegate;
// Now set our subdelegate to null to help indicate that
// we're no longer in a transactional situation.
this.subdelegate = null;
}
// situation.
assert this.delegate != null;
assert !(this.delegate instanceof CdiTransactionScopedEntityManager);
assert this.delegate.isOpen();
assert this.subdelegate == null;
returnValue = this.delegate;
} else {
if (this.delegate != null && !this.delegate.isOpen()) {
// subdelegate field.
assert this.delegate instanceof CdiTransactionScopedEntityManager;
assert this.subdelegate != null;
assert !(this.subdelegate instanceof CdiTransactionScopedEntityManager);
assert this.subdelegate.isOpen();
this.delegate = this.subdelegate;
this.subdelegate = null;
}
if (!(this.delegate instanceof CdiTransactionScopedEntityManager)) {
// not a CdiTransactionScopedEntityManager.
assert this.subdelegate == null;
assert this.delegate == null ? true : this.delegate.isOpen();
// Since we're in a transaction, we have to look for
// the @TransactionScoped EntityManager that is
// associated with the JTA transaction. So look for
// an EntityManager bean annotated with, among other
// possible things, @CdiTransactionScoped
// and @ContainerManaged.
final Set<Annotation> selectionQualifiers = new HashSet<>(this.suppliedQualifiers);
selectionQualifiers.remove(Extended.Literal.INSTANCE);
selectionQualifiers.remove(JpaTransactionScoped.Literal.INSTANCE);
selectionQualifiers.remove(NonTransactional.Literal.INSTANCE);
selectionQualifiers.add(CdiTransactionScoped.Literal.INSTANCE);
selectionQualifiers.add(ContainerManaged.Literal.INSTANCE);
final Set<Bean<?>> cdiTransactionScopedEntityManagerBeans = this.beanManager.getBeans(CdiTransactionScopedEntityManager.class, selectionQualifiers.toArray(new Annotation[selectionQualifiers.size()]));
assert cdiTransactionScopedEntityManagerBeans != null;
assert !cdiTransactionScopedEntityManagerBeans.isEmpty();
@SuppressWarnings("unchecked") final Bean<?> cdiTransactionScopedEntityManagerBean = (Bean<CdiTransactionScopedEntityManager>) this.beanManager.resolve(cdiTransactionScopedEntityManagerBeans);
assert cdiTransactionScopedEntityManagerBean != null;
assert context.getScope().equals(cdiTransactionScopedEntityManagerBean.getScope());
// Using that bean, check the Context to see if there's
// already a container-managed EntityManager enrolled in
// the transaction (without accidentally creating a new
// one, hence the single-argument Context#get(Contextual)
// invocation, not the dual-argument
// Context#get(Contextual, CreationalContext) one). We
// have to do this to honor section 7.6.3.1 of the JPA
// specification.
final Object existingContainerManagedCdiTransactionScopedEntityManager = context.get(cdiTransactionScopedEntityManagerBean);
if (existingContainerManagedCdiTransactionScopedEntityManager != null) {
// transactional or not.
throw new CreationException(Messages.format("preexistingExtendedEntityManager", cdiTransactionScopedEntityManagerBean, existingContainerManagedCdiTransactionScopedEntityManager));
}
// OK, there's no existing CDI-transaction-scoped
// EntityManager. Let's cause one to be created.
@SuppressWarnings("unchecked") final CdiTransactionScopedEntityManager cdiTransactionScopedEntityManager = (CdiTransactionScopedEntityManager) this.beanManager.getReference(cdiTransactionScopedEntityManagerBean, CdiTransactionScopedEntityManager.class, this.beanManager.createCreationalContext(cdiTransactionScopedEntityManagerBean));
assert cdiTransactionScopedEntityManager != null;
// "through" to be *its* delegate.
if (this.delegate == null) {
this.subdelegate = EntityManagers.createContainerManagedEntityManager(this.instance, this.suppliedQualifiers);
} else {
assert !(this.delegate instanceof CdiTransactionScopedEntityManager);
assert this.subdelegate == null;
this.subdelegate = this.delegate;
}
assert this.subdelegate != null;
cdiTransactionScopedEntityManager.setDelegate(this.subdelegate);
this.delegate = cdiTransactionScopedEntityManager;
// extended EntityManager.
if (this.isSynchronized) {
this.delegate.joinTransaction();
}
}
assert this.delegate != null;
assert this.delegate.isOpen();
returnValue = this.delegate;
}
return returnValue;
}
use of jakarta.enterprise.inject.CreationException in project helidon by oracle.
the class JedisExtension method addBeans.
private void addBeans(@Observes final AfterBeanDiscovery event, final BeanManager beanManager) throws IntrospectionException {
if (event != null && beanManager != null) {
for (final String instanceName : this.instanceNames) {
if (instanceName != null) {
final Set<Annotation> qualifiers;
if (instanceName.equals("default")) {
qualifiers = Collections.singleton(Default.Literal.INSTANCE);
} else {
qualifiers = Collections.singleton(NamedLiteral.of(instanceName));
}
event.<JedisPoolConfig>addBean().addTransitiveTypeClosure(JedisPoolConfig.class).scope(ApplicationScoped.class).addQualifiers(qualifiers).produceWith((instance) -> {
final JedisPoolConfig returnValue = new JedisPoolConfig();
try {
this.configure(instance.select(Config.class).get(), returnValue, JedisPoolConfig.class, instanceName);
} catch (final IntrospectionException | ReflectiveOperationException e) {
throw new CreationException(e.getMessage(), e);
}
return returnValue;
});
final Annotation[] qualifiersArray = qualifiers.toArray(new Annotation[qualifiers.size()]);
event.<JedisPool>addBean().addTransitiveTypeClosure(JedisPool.class).scope(ApplicationScoped.class).addQualifiers(qualifiers).produceWith(instance -> {
return produceJedisPool(instance, instanceName, qualifiersArray);
}).disposeWith((p, instance) -> p.destroy());
event.<Jedis>addBean().addTransitiveTypeClosure(Jedis.class).scope(Dependent.class).addQualifiers(qualifiers).produceWith(instance -> instance.select(JedisPool.class, qualifiersArray).get().getResource()).disposeWith((j, instance) -> j.close());
}
}
}
}
use of jakarta.enterprise.inject.CreationException in project helidon by oracle.
the class NarayanaExtension method afterBeanDiscovery.
/*
* Instance methods.
*/
/**
* Adds a synthetic bean that creates a {@link Transaction} in
* {@linkplain TransactionScoped transaction scope}.
*
* @param event the {@link AfterBeanDiscovery} event fired by the
* CDI container; may be {@code null} in which case no action will
* be taken
*
* @param beanManager the {@link BeanManager} in effect; may be
* {@code null} in which case no action will be taken
*/
private void afterBeanDiscovery(@Observes final AfterBeanDiscovery event, final BeanManager beanManager) {
final String cn = NarayanaExtension.class.getName();
final String mn = "afterBeanDiscovery";
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.entering(cn, mn, new Object[] { event, beanManager });
}
if (event != null && beanManager != null) {
// Weld registers a UserTransaction bean well before this
// observer method fires. OpenWebBeans does not. We need
// to handle both cases since this is not part of the CDI
// specification.
Collection<? extends Bean<?>> beans = beanManager.getBeans(UserTransaction.class);
if (beans == null || beans.isEmpty()) {
event.addBean().types(UserTransaction.class).addQualifiers(Any.Literal.INSTANCE, Default.Literal.INSTANCE).scope(Dependent.class).createWith(cc -> com.arjuna.ats.jta.UserTransaction.userTransaction());
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.logp(Level.FINE, cn, mn, "addedUserTransactionBean");
}
}
event.addBean().id(Transaction.class.getName()).types(Transaction.class).addQualifiers(Any.Literal.INSTANCE, // OpenWebBeans does not add these
Default.Literal.INSTANCE).scope(TransactionScoped.class).createWith(cc -> {
try {
return CDI.current().select(TransactionManager.class).get().getTransaction();
} catch (final SystemException systemException) {
throw new CreationException(systemException.getMessage(), systemException);
}
});
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.logp(Level.FINE, cn, mn, "addedTransactionBean");
}
beans = beanManager.getBeans(JTAEnvironmentBean.class);
if (beans == null || beans.isEmpty()) {
event.addBean().addTransitiveTypeClosure(JTAEnvironmentBean.class).addQualifiers(Any.Literal.INSTANCE, Default.Literal.INSTANCE).scope(Singleton.class).createWith(cc -> DEFAULT_JTA_ENVIRONMENT_BEAN);
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.logp(Level.FINE, cn, mn, "addedJtaEnvironmentBeanBean");
}
}
}
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.exiting(cn, mn);
}
}
use of jakarta.enterprise.inject.CreationException in project helidon by oracle.
the class JpaExtension method maybeAddPersistenceProviderBean.
/**
* Given a {@link PersistenceUnitInfo} and a {@link Collection} of
* {@link PersistenceProvider} instances representing already
* "beanified" {@link PersistenceProvider}s, adds a CDI bean for
* the {@linkplain
* PersistenceUnitInfo#getPersistenceProviderClassName()
* persistence provider referenced by the supplied
* <code>PersistenceUnitInfo</code>} if the supplied {@link
* Collection} of {@link PersistenceProvider}s does not contain
* an instance of it.
*
* @param event the {@link AfterBeanDiscovery} event that will do
* the actual bean addition; must not be {@code null}
*
* @param persistenceUnitInfo the {@link PersistenceUnitInfo}
* whose {@linkplain
* PersistenceUnitInfo#getPersistenceProviderClassName()
* associated persistence provider} will be beanified; must not be
* {@code null}
*
* @param providers a {@link Collection} of {@link
* PersistenceProvider} instances that represent {@link
* PersistenceProvider}s that have already had beans added for
* them; may be {@code null}
*
* @exception NullPointerException if {@code event} or {@code
* persistenceUnitInfo} is {@code null}
*
* @exception ReflectiveOperationException if an error occurs
* during reflection
*/
private void maybeAddPersistenceProviderBean(final AfterBeanDiscovery event, final PersistenceUnitInfo persistenceUnitInfo, final Collection<? extends PersistenceProvider> providers) throws ReflectiveOperationException {
final String cn = JpaExtension.class.getName();
final String mn = "maybeAddPersistenceProviderBean";
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.entering(cn, mn, new Object[] { event, persistenceUnitInfo, providers });
}
Objects.requireNonNull(event);
Objects.requireNonNull(persistenceUnitInfo);
final String providerClassName = persistenceUnitInfo.getPersistenceProviderClassName();
if (providerClassName != null) {
boolean add = true;
if (providers != null && !providers.isEmpty()) {
for (final PersistenceProvider provider : providers) {
if (provider != null && provider.getClass().getName().equals(providerClassName)) {
add = false;
break;
}
}
}
if (add) {
// The PersistenceProvider class in question is not one we
// already loaded. Add a bean for it too.
String persistenceUnitName = persistenceUnitInfo.getPersistenceUnitName();
if (persistenceUnitName == null || persistenceUnitName.isEmpty()) {
persistenceUnitName = DEFAULT_PERSISTENCE_UNIT_NAME;
this.defaultPersistenceUnitInEffect = true;
}
// Provide support for, e.g.:
// @Inject
// @Named("test")
// private PersistenceProvider providerProbablyReferencedFromAPersistenceXml;
event.addBean().types(PersistenceProvider.class).scope(ApplicationScoped.class).addQualifiers(NamedLiteral.of(persistenceUnitName)).createWith(cc -> {
try {
ClassLoader classLoader = persistenceUnitInfo.getClassLoader();
if (classLoader == null) {
classLoader = Thread.currentThread().getContextClassLoader();
}
assert classLoader != null;
@SuppressWarnings("unchecked") final Class<? extends PersistenceProvider> c = (Class<? extends PersistenceProvider>) Class.forName(providerClassName, true, classLoader);
return c.getDeclaredConstructor().newInstance();
} catch (final ReflectiveOperationException reflectiveOperationException) {
throw new CreationException(reflectiveOperationException.getMessage(), reflectiveOperationException);
}
});
}
}
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.exiting(cn, mn);
}
}
Aggregations