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

问题描述 投票:0回答:1

首先,抱歉我的英语。我有一个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),设置较旧的Bean到ViewScoped(所以我可以自然地在我的数据库上重现更新),并让这个新的Bean处理其他视图的请求?

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

'保存'方法:

    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();
}
jsf primefaces
1个回答
1
投票

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

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

2)改变你的支持bean的范围。会话范围并不理想,因为它可以在内存中保留很长时间。您可能会意识到需要手动清理它。更好的是ViewScoped bean,因为它允许您使用通过几个步骤加载的实体。当用户离开页面时,它会被清除。

@javax.faces.bean.ViewScoped
@javax.faces.bean.ManagedBean
public class SomethingBean {
    ......
}
© www.soinside.com 2019 - 2024. All rights reserved.