我目前正在远离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();
}
但是当外部事件表明缓存已经过时时,这就失去了重新创建缓存的能力。我该怎么办呢?
答案 0 :(得分: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同步机制来同步观察者和生成器方法。