Weld SiteCommunity Documentation
It would not be notified, as @Personal
is not a qualifier of the event being fired.
Or to put it more formally, @Updated
and @Personal
do not form a subset of @Blog
and @Updated
.
Transactional observers receive their event notifications during the
before or after completion phase of the transaction in which the event
was raised. For example, the following observer method needs to refresh
a query result set that is cached in the application context, but only
when transactions that update the Category
tree succeed:
public void refreshCategoryTree(@Observes(during = AFTER_SUCCESS) CategoryUpdateEvent event) { ... }
There are five kinds of transactional observers:
IN_PROGRESS
observers are called immediately (default)AFTER_SUCCESS
observers are called during the after completion phase
of the transaction, but only if the transaction completes successfullyAFTER_FAILURE
observers are called during the after completion phase
of the transaction, but only if the transaction fails to complete
successfullyAFTER_COMPLETION
observers are called during the after completion
phase of the transactionBEFORE_COMPLETION
observers are called during the before completion
phase of the transactionTransactional observers are very important in a stateful object model because state is often held for longer than a single atomic transaction.
Imagine that we have cached a JPA query result set in the application scope:
import javax.ejb.Singleton;
import javax.enterprise.inject.Produces;
@ApplicationScoped @Singleton
public class Catalog {
@PersistenceContext EntityManager em;
List<Product> products;
@Produces @Catalog
List<Product> getCatalog() {
if (products==null) {
products = em.createQuery("select p from Product p where p.deleted = false")
.getResultList();
}
return products;
}
}
From time to time, a Product
is created or deleted. When this occurs,
we need to refresh the Product
catalog. But we should wait until
after the transaction completes successfully before performing this
refresh!
The bean that creates and deletes `Product`s could raise events, for example:
import javax.enterprise.event.Event;
@Stateless
public class ProductManager {
@PersistenceContext EntityManager em;
@Inject @Any Event<Product> productEvent;
public void delete(Product product) {
em.delete(product);
productEvent.select(new AnnotationLiteral<Deleted>(){}).fire(product);
}
public void persist(Product product) {
em.persist(product);
productEvent.select(new AnnotationLiteral<Created>(){}).fire(product);
}
...
}
And now Catalog
can observe the events after successful completion of
the transaction:
import javax.ejb.Singleton;
@ApplicationScoped @Singleton
public class Catalog {
...
void addProduct(@Observes(during = AFTER_SUCCESS) @Created Product product) {
products.add(product);
}
void removeProduct(@Observes(during = AFTER_SUCCESS) @Deleted Product product) {
products.remove(product);
}
}
Weld API offers slight advantage when dealing with events - org.jboss.weld.events.WeldEvent
, an augmented version of javax.enterprise.event.Event
.
Currently there is only one additional method, select(Type type, Annotation... qualifiers)
.
This method allows to perform well-known selection with java.lang.reflect.Type
as parameter which means things can get pretty generic.
While there are no limitations to what you can select, there are limitation to the WeldEvent
instance you perform selection on.
In order to preserve type-safety, you have to invoke this method on WeldInstance<Object>
.
Using any other parameter will result in IllegalStateException
.
Usage looks just as you would except:
@Inject
WeldEvent<Object> event;
public void selectAndFireEventForType(Type type) {
event.select(type).fire(new Payload());
}