You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PrimeFaces DataTable置于表单外时提交非AJAX表单导致选中字段被置为null的版本差异问题及行为合理性咨询

PrimeFaces DataTable Selection Reset to Null When Outside Form (Non-AJAX Submit)

Let's break down this behavior change in PrimeFaces and address your questions clearly:

Observed Behavior

When placing a <p:dataTable> outside an <h:form> and submitting a non-AJAX form, the view field bound to the selection attribute (like DtView.selectedEntry in your example) gets reset to null. This happens consistently in PrimeFaces 10.0.1 and newer versions, but in 10.0.0 and 8.x releases, the selected value remains unchanged.

Example Code

XHTML

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:p="http://primefaces.org/ui" xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>PrimeFaces Test</title>
</h:head>
<h:body>
<p:dataTable id="data-table" var="entry" value="#{dtView.entries}" rowKey="#{entry.id}" selection="#{dtView.selectedEntry}" selectionMode="single">
<p:column headerText="Entry">
<h:outputText value="#{entry}" />
</p:column>
</p:dataTable>
<h:form id="frmTest">
<div>
<p:outputLabel for="@next" value="Selected: "/>
<h:outputText id="selected-entry" value="#{dtView.selectedEntry}" />
</div>
<div>
<p:commandButton value="save input" ajax="false" immediate="true" update="@form :data-table" action="#{dtView.submit()}" />
</div>
</h:form>
</h:body>
</html>

View Layer (Java)

@Data
@Named
@ViewScoped
public class DtView implements Serializable {
    private List<Product> entries;
    private Product selectedEntry;

    @PostConstruct
    void setup() {
        entries = List.of(
            new Product(1, "entry 1"),
            new Product(2, "entry 2"),
            new Product(3, "entry 3")
        );
        selectedEntry = entries.get(0);
    }

    public String submit() {
        System.out.println("Selected entry: " + selectedEntry);
        return null;
    }
}

Console Output Comparison

  • PrimeFaces 11.0.0: Selected entry: null
  • PrimeFaces 10.0.0: Selected entry: Product(id=1, name=entry 1)

Workarounds

To avoid the selected field being reset to null, use one of these approaches:

  • Move the <p:dataTable> inside the <h:form>: This ensures it won't be processed during the request values application phase, as it aligns with PrimeFaces' intended usage for selection features.
  • Use an AJAX-submit button: AJAX requests only process components within the specified execute scope, so the external dataTable won't interfere with the selection value.

Clarification on the Behavior

First, as noted by Jasper, PrimeFaces' SelectionFeature requires <p:dataTable> to be placed inside a form for proper functionality. So your original setup (dataTable outside the form) is technically against the component's designed usage.

To answer your question: Yes, the newer PrimeFaces behavior is more aligned with logical component processing. When you submit a full non-AJAX request, JSF processes all components in the view that have a decode method—even those outside forms. In newer versions, the SelectionFeature's decode logic explicitly sets the selection to null when no row keys are submitted (which happens because the dataTable is outside the form, so its request parameters aren't sent with the form submission).

Your expectation that "values outside the form shouldn't be modified" is understandable, but JSF's component processing model doesn't strictly enforce this for non-AJAX requests. Older versions either skipped setting null (10.0.0 had a check for empty row keys that was removed in 10.0.1) or only set null in limited scenarios (8.x). The updated behavior ensures consistency: if the component can't confirm a valid selection from the request, it resets the bound value.

Underlying Code Change

The behavior shift stems from modifications to the SelectionFeature class:

  • PrimeFaces 8: Only called table.setSelection(null); in specific edge cases.
  • PrimeFaces 10.0.0: The decodeSingleSelection() method avoided calling setSelection() due to a !rowKeys.isEmpty() check, which prevented nulling the value when no row keys were present.
  • PrimeFaces 10.0.1+ (including 11.0.0): The empty row keys check was removed, so decodeSingleSelection() now always calls setSelection()—setting the value to null when no valid row keys are submitted from the dataTable.

内容的提问来源于stack exchange,提问作者Jane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 16:32:50