如何在RequestScoped视图上更新数据库中的bean?

时间:2017-03-27 14:46:31

标签: jsf primefaces

首先,对不起我的英语。我有一个RequestScoped ManagedBean,以便将参数发送到其他视图,而不会出现The scope of the object referenced by expression is shorter than the referring managed beans错误。我在同一个RequestScoped视图中也有一个显示这些bean对象的p:dataTable,每行都有一个更新按钮,它将该bean检索到同一视图中的另一个表单,以便用新值进行更新。

问题是,当我点击提交按钮来记录新值时,会创建另一条记录,而不是更新的旧记录。当然,因为按下提交按钮(RequestScoped)时bean被杀死,所以在DB中创建一个新bean和另一条记录。如何在此范围内修复它?

我已经看到了使用@PostConstruct here的一些替代方案,但我并不完全确定它会解决我的具体问题。

编辑:

在进一步研究this topic之后,我又出现了另一个疑问:我在两个视图中使用相同的Bean(在我的例子中是ProjectBean),我应该创建一个带有RequestScoped注释的新Bean(类似于ProjectIdBean),将旧版本设置为ViewScoped(这样我可以自然地在我的数据库上重现更新),并让这个新Bean处理其他视图的请求?

提交按钮: <p:commandButton value="Gravar" action="#{projetoBean.gravar}" process="@form" update="@form :formTabelaProjetos:tabelaProjetos" />

'Gravar'方法:

    public void gravar() {
    System.out.println("Gravando projeto " + this.projeto.getNome());

    ProjetoDAO dao = new ProjetoDAO();

    if (this.projeto.getId() == null) {
        dao.adiciona(this.projeto);
        projetosAtivos = this.getProjetosAtivos();
    } else {
        dao.atualiza(this.projeto);
    }

    this.projeto = new Projeto();
}

1 个答案:

答案 0 :(得分:1)

您可以使用请求范围的支持bean来更新实体。问题在于,呈现页面时请求生命周期结束。因此,您加载的所有内容都会被丢弃。提交创建另一个请求,该请求将尝试重新加载资源,但这是与前一个请求不同的请求,例如,请求参数通常不包含程序员期望的内容。但这就是您已经发现的。有两种方法可以解决该问题:

1)使用简单的getter和setter在请求范围内的bean中设置“ String,Integer”和类似变量,这些变量用于重建和修改要更新的实体。这对程序员来说不方便,但是请求范围内的Bean可以节省服务器资源。

2)更改辅助bean的范围。会话范围不是理想的,因为它可以在内存中保留很长时间。您可能会意识到需要手动清理它。 ViewScoped bean更好,因为它使您可以处理通过多个步骤加载的实体。当用户离开页面时,它将消失。

@javax.faces.bean.ViewScoped
@javax.faces.bean.ManagedBean
public class SomethingBean {
    ......
}