我解决了这个问题,它是通过使用@RequestScoped而不是@SessionScoped我的页面控制器豆引起的。
我在做什么是使用编辑链接从数据表中传递当前产品对象到doEditProduct方法。
<h:dataTable id="viewProductsTable" value="#{productController.products}" var="_product"
styleClass="data-table" headerClass="table-header" rowClasses="table-row">
<h:column>
<f:facet name ="header">
<h:outputText value="Product Name" />
</f:facet>
<h:outputText value="#{_product.productName}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Goal"/>
</f:facet>
<h:outputText value="#{_product.goal}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Details"/>
</f:facet>
<h:outputText value="#{_product.description}"/>
</h:column>
<h:column>
<h:form>
<h:commandLink value="Edit" action="#{productController.doEditProduct(_product)}"/>
</h:form>
</h:column>
</h:dataTable>
的productController.doEditProduct方法然后打开编辑页面
public String doEditProduct(Product product) {
this.product = product;
return "edit-product.xhtml";
编辑页面包含一个简单的编辑形式
<h:form id="addProductForm">
<h:panelGrid columns="2" columnClasses="top-alignment, top-alignment">
<h:outputLabel for="product-name" value="Product Name"/>
<h:outputText value="#{productController.product.productName}" id="product-name" />
<h:outputLabel for="goal" value="Goal" />
<h:inputTextarea value="#{productController.product.goal}" id="goal" rows="10" cols="100" />
<h:outputLabel for="details" value="Details" />
<h:inputTextarea value="#{productController.product.description}" id="details" rows="20" cols="100"/>
<f:facet name="footer">
<h:panelGroup style="padding-top: 15px; display: inline-block; float: right; white-space: nowrap">
<h:commandButton id="submit" value="Save" action="#{productController.updateProduct()}" class="button" />
<h:button id="Cancel" outcome="index.xhtml" value="Cancel" class="button"/>
</h:panelGroup>
</f:facet>
</h:panelGrid>
</h:form>
此时产品数据显示在页面上。然而,当点击保存按钮并运行更新方法时
public String updateProduct() {
try {
log.log(Level.INFO, "Updating: {0}", product.getGoal());
productFacade.edit(product);
} catch (Exception e) {
log.log(Level.WARNING, e.toString());
String errorMessage = getRootErrorMessage(e);
FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, "could not update product");
facesContext.addMessage(null, m);
return "";
}
return "index.xhtml";
任何已被禁用或只读的字段被设置为空。实际上,页面上任何位置的任何非输入字段都设置为空。
控制器类上的@RequestScope意味着类正在被重新实例化,因此存储在产品中的对象被分配了PostConstruct方法中的新对象。可编辑字段中的值被转移到这个新对象,并且不可编辑字段被设置为空。与数据库合并意味着字段中的数据被删除。
使用@SessionScoped意味着控制器bean跨页请求继续存在。 (我需要提醒自己的基本网页生命周期)
希望这可以帮助任何其他人有这种行为。
格雷厄姆
请问您可以发布一些代码。因为我无法重现此行为所有预期的工作,与残疾人和只读后提交值保持正常。 – pL4Gu33