如何有效地更新多个类中包含的属性?

时间:2013-11-01 14:29:45

标签: jsf-2 cdi weld2

我有这个简单的模式,其中控制器/支持bean管理@ViewScoped上下文中的单个实体实例。该视图需要几个支持bean并显示信息。 Andy Gibson在blog post中描述了我正在使用的方法。

现在我需要显示有关两个实体的信息,一个人及其联系人:

@Entity
public class Person {
    @Id @Generated 
    private Long id;

    @OneToMany(mappedBy = "owner") 
    private Set<Contact> contacts = new LinkedHashSet<>();
}

@Entity
public class Contact {
    @Id @Generated 
    private Long id;

    private String content;

    @ManyToOne
    private Person owner;

    @OneToMany
    private Set<File> attachments;
}

有一个ContactMgr和一个PersonMgr,我首先通过Person完全加载f:viewAction。然后,我会显示该人员的联系人列表,并让用户在rich:popupPanel

中对其进行编辑
<h:dataTable value="#{personMgr.instance.contacts}" var="c">
    <h:column><a4j:commandLink value="#{c.content}"
        actionListener="#{contactMgr.setId(c.id)}"
        action="#{contactMgr.fullInit()}"
        render=":contactInnards"
        oncomplete="#{rich:component('contactPanel')}.show();" />
    </h:column>
 </h:dataTable>

点击该链接可加载所选联系人,并允许用户根据自己的喜好进行编辑。然后,用户单击“保存”并保持更改。一切都很好。

但现在我想重新呈现联系人列表。如何让PersonMgr知道已更改的联系人?联系人列表已在前一段时间填充,未在ContactMgr中更改。

我已经看过三个解决方案了:

  • 直接在ContactMgr上设置联系人,但我确实需要在显示弹出窗口之前初始化更多字段,因为我不想为每个联系人产生这样的费用。
  • 完整的网站重新加载是可能的,但也非常昂贵。
  • 使用@Observe我恐怕需要十几种方法,每个方法一个,我附加到Person

那么,我怎样才能有效地将变更信息从一个bean分发给包含已编辑实体(现在陈旧)副本的其他bean?

1 个答案:

答案 0 :(得分:0)

我开始认为这个问题实际上就像缓存失效一样 - 一个已知的难题。我可能会做一些事情来扩展@Observe(notifyOberserver = IF_EXISTS)的想法并让它工作而不会淹没在新的方法中。

但是我发现只需将支持dataTable的任务移到ContactMgr并具有填充,选择和更新列表的所有逻辑,一个班级创造了奇迹以完全避免这个问题。