首先,对不起我的英语。我有一个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();
}
答案 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 {
......
}