mabi
mabi

Reputation: 5306

How can I update a collection that is @Produces @ApplicationScoped?

I'm currently migrating away from Seam's @Factory annotation. Combined with @Observer, I could do this:

@Factory(value = "optionsList", scope = ScopeType.APPLICATION)
@Observer("entity.modified")
public List<MyBean> produceEntityOptions() {
    List l = getEm().createQuery('select e from entity e').getResultList();
    Contexts.getApplicationContext().set("optionsList", l);
    return l;
}

Which would cache a list of possible options for use in e.g. <f:selectItems> (the actual computation can be more complicated).

I've translated this for use with CDI to

@Produces @Named("optionsList") @ApplicationScoped
public List<MyBean> produceEntityOptions() {
    return getEm().createQuery('select e from entity e').getResultList();
}

but this loses the ability to recreate the cache (only) when an external event signals the cache has gone stale. How can I get that back?

Upvotes: 3

Views: 727

Answers (1)

rdcrng
rdcrng

Reputation: 3443

Here's what you could do:

@ApplicationScoped
public class MyListProducer {

    // the current list
    private List<MyBean> listOfBeans;

    // resets / reloads/ refreshes list
    private void loadList() {
        this.listOfBeans = getEm().createQuery('select e from entity e').getResultList();
    }

    // initialize the list
    @PostConstruct
    protected void postConstruct() {
        loadList();
    }

    // listen for the stale event - you'll have to create a type (maybe even qualifiers) yourself
    private void resetList(@Observes MyCustomListIsStaleEvent evt) {
        loadList();
    }

    // the producer - to ensure that the producer is called after you refresh the list, make the list of scope @Dependent instead of @ApplicationScoped
    @Produces @Named("optionsList")
    protected List<MyBean> getList() {
        return this.listOfBeans;
    }
}

I think that in effect, this is what you want. But I don't exclude the possibility that there might be differences - don't know Seam very much.

Side note: You should think about synchronizing the observer and the producer methods, either with plain old synchronization or by making the above a stateful session bean and taking advantage of EJB synchronization mechanisms.

Upvotes: 3

Related Questions