DominikM
DominikM

Reputation: 1052

JSF + primefaces calling getter way too much times

I read all answers on this topic (not only) on SO, but none of this solves my problem. I have datatable:

<p:dataTable 
                value="#{reportBean.reportData.rows}"
                var="row" 
                styleClass="listBlock dataTableOverflowAuto fullScreenTable"
                rendered="#{!reportBean.reportData.grouped}">
                 <f:facet name="header">
                    #{msg['report.table.header']}
                </f:facet>

                <p:column>
                    #{row.integrationName}
                </p:column>

                <p:column>
                    #{row.integrationId}
                </p:column>

                <p:column>
                    #{row.service}
                </p:column>

                <p:columns value="#{reportBean.reportData.columns}"
                           var="column">  
                    <f:facet name="header">  
                        #{column}
                    </f:facet>  
                    <h:outputText value="#{row.getData(column)}" escape="false" />  
                </p:columns>

getReportData() on reportBean is very simple (no calculation):

public ReportDataInterface getReportData() {
        return reportData;
}

And the data returned are:

public class NoneGroupedReportData implements ReportDataInterface {
    private int counter = 0;
    Logger logger = LoggerFactory.getLogger(getClass());
    private List<String> columns = new LinkedList<String>();
    public void addRow(Row row) {
        addColumns(row);
    }

    public List<String> getColumns() {
        counter++;
        logger.debug("getColumns called {} times", counter);
        return columns;
    }

....

And the result is

2013-05-15 07:38:07,405 () DEBUG NoneGroupedReportData - getColumns called 21600 times

For dataTable with ~30 rows and 10 columns.

I know why JSF calls getters many times, but almost 22k, why? When i need more results (>1000) it will not render in 5 minutes, because it endlessly calls this getter. Where is the problem and how can i achieve the state in which getColumns() is called for each row max 5~10 times?

I have tried using jstl c:set "caching" but without any result (http://qussay.com/2013/04/19/caching-and-reusing-an-evaluated-el-expression-in-jsf/)

EDIT: My guess is that getter calling is not "wrong" but sign that i am using dataTable in the wrong way.

Upvotes: 1

Views: 1709

Answers (1)

Rodmar Conde
Rodmar Conde

Reputation: 956

The problem is that you are accessing two times the same data structure,

N: <p:dataTable value="#{reportBean.reportData.rows}" ...

and then INSIDE the same p:dataTable you are using

M: <p:columns value="#{reportBean.reportData.columns}" ...

That causes a N * M product that a the end gives your 21600 times, because you are accessing the same data structure in two nested tags...

It is not clear what kind of datatable are you trying to construct, but I think you should reorganize your data structure.

The simpler solution, in case you are trying to put multiple values inside one single column for each row will be changing M to:

M: <p:columns value="#{rows.columns}" ...

But that will involve changing your data structure to put your columns component into your rows component.

Regards,

Upvotes: 5

Related Questions