JSF + primefaces调用getter方式太多次了

时间:2013-05-15 05:53:05

标签: java performance jsf primefaces

我在SO上阅读了关于这个主题(不仅仅是)的所有答案,但这些都没有解决我的问题。 我有数据表:

<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>
reportBean上的

getReportData()非常简单(无需计算):

public ReportDataInterface getReportData() {
        return reportData;
}

返回的数据是:

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;
    }

....

结果是

  

2013-05-15 07:38:07,405()DEBUG NoneGroupedReportData - getColumns   叫21600次

对于包含~30行和10列的dataTable。

我知道为什么JSF会多次调用getter,但差不多22k,为什么?当我需要更多结果(> 1000)时,它将无法在5分钟内渲染,因为它无休止地调用此getter。 问题出在哪里?如何实现每行调用getColumns()最多5~10次的状态?

我尝试过使用jstl c:设置“缓存”但没有任何结果(http://qussay.com/2013/04/19/caching-and-reusing-an-evaluated-el-expression-in-jsf/

编辑:我的猜测是,getter调用并非“错误”,而是表示我以错误的方式使用dataTable。

1 个答案:

答案 0 :(得分:5)

问题是您正在访问两次相同的数据结构,

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

然后 INSIDE 使用相同的p:dataTable

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

这会导致 N * M 产品的结尾为您提供21600次,因为您正在访问两个嵌套标记中的相同数据结构 ...

目前尚不清楚您想要构建哪种数据表,但我认为您应该重新组织您的数据结构。

更简单的解决方案如果您尝试将多个值放入每行的一个列中,则会将M更改为:

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

但这将涉及更改您的数据结构,以将组件放入组件。

此致