문제

I have a <p:dataTable> as follows.

<p:dataTable var="row" value="#{testManagedBean.list}">
    <p:column>
        <h:outputText value="#{row.subCatId}"/>
    </p:column>

    <p:column>
        <p:commandLink process="@this">
            <h:outputText value="#{row.subCatName}"/>
            <f:setPropertyActionListener target="#{testManagedBean.subCatName}" value="#{row.subCatName}"/>
        </p:commandLink>
    </p:column>
</p:dataTable>

The corresponding RequestScoped managed bean is as follows.

@ManagedBean
@RequestScoped
public final class TestManagedBean
{
    @EJB
    private final TestBeanLocal testService=null;
    private List<SubCategory>list;
    private String subCatName;

    @PostConstruct
    private void init()
    {
        list=testService.getSubCategoryList();
    }

    public List<SubCategory> getList() {
        return list;
    }

    public String getSubCatName() {
        return subCatName;
    }

    public void setSubCatName(String subCatName) {
        System.out.println("setSubCatName() called : "+subCatName);
        this.subCatName = subCatName;
    }
}

When <p:commandLink> inside <p:dataTable> is clicked, the corresponding setter method associated with <f:setProperyActionListener> (setSubCatName()) is called and the value is correctly set to the target property which is subCatName in this managed bean.

I have avoided many things like paging to have a minimal example.


Now, I need to populate this <p:dataTable> lazily. I'm changing this <p:dataTable> and the corresponding managed bean as follows.

<p:dataTable var="row" value="#{testManagedBean}" lazy="true" rows="10" rowIndexVar="rowIndex">
    <p:column>
        <h:outputText value="#{row.subCatId}"/>
    </p:column>

    <p:column>
        <p:commandLink process="@this">
            <h:outputText value="#{row.subCatName}"/>
            <f:setPropertyActionListener target="#{testManagedBean.subCatName}" value="#{row.subCatName}"/>
        </p:commandLink>
    </p:column>
</p:dataTable>

And the associated JSF managed is given below.

@ManagedBean
@RequestScoped
public final class TestManagedBean extends LazyDataModel<SubCategory> implements Serializable
{
    @EJB
    private final TestBeanLocal testService=null;
    private String subCatName;
    private static final long serialVersionUID = 1L;

    public String getSubCatName() {
        return subCatName;
    }

    public void setSubCatName(String subCatName) {
        System.out.println("setSubCatName() called : "+subCatName);
        this.subCatName = subCatName;
    }

    @Override
    public List<SubCategory> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters)
    {
        setRowCount(4); //Just an example. Otherwise, fetch from the database.
        return testService.getSubCategoryList(first, pageSize, sortField, sortOrder, filters);
    }
}

Now, when <p:commandLink> inside <p:dataTable> is clicked, the corresponding setter method associated with <f:setProperyActionListener> (setSubCatName()) is not invoked.

The setSubCatName() is only invoked, when the managed bean is decorated with a broader scope like @ViewScoped (in case of lazy is set to true)

Why doesn't <f:setPropertyActionListener> work with a request scoped managed managed bean, when a <p:dataTable> (also true for <p:dataGrid>) is lazily loaded?

Is it mandatory to designate a managed bean with a broader than a request scope in such cases?

도움이 되었습니까?

해결책

yes it is mandatory because the underlying model has to be the same instance. even if it has the same values it won't work.

like you, i've met this behavior: primefaces datatable lazy loading and commandbutton per row

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top