3

我目前正在远离 Seam 的@Factory注释。结合@Observer,我可以这样做:

@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;
}

这将缓存一个可能的选项列表以用于例如<f:selectItems>(实际计算可能更复杂)。

我已将其翻译为与 CDI 一起使用

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

但这会失去重新创建缓存的能力(仅)当外部事件发出缓存已过时的信号时。我怎样才能把它拿回来?

4

1 回答 1

3

这是你可以做的:

@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;
    }
}

我认为实际上,这就是你想要的。但我不排除可能存在差异的可能性——不太了解Seam。

旁注:您应该考虑同步观察者和生产者方法,或者使用普通的旧同步,或者通过使上述有状态会话 bean 并利用 EJB 同步机制。

于 2013-09-12T21:35:52.787 回答