From 4f3be018cfbeea21fc627edacfd72b199b6ee6a8 Mon Sep 17 00:00:00 2001 From: Melloware Date: Mon, 19 Feb 2024 10:19:32 -0500 Subject: [PATCH] Fix #11452 - 13.0.6 DataTable: LazyDataModel.load gets invoked multiple times (#11461) --- .../component/datatable/DataTableRenderer.java | 18 ++++++++---------- .../org/primefaces/model/LazyDataModel.java | 10 +++++++++- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/primefaces/src/main/java/org/primefaces/component/datatable/DataTableRenderer.java b/primefaces/src/main/java/org/primefaces/component/datatable/DataTableRenderer.java index caf2c598d9..847e2a1059 100644 --- a/primefaces/src/main/java/org/primefaces/component/datatable/DataTableRenderer.java +++ b/primefaces/src/main/java/org/primefaces/component/datatable/DataTableRenderer.java @@ -1086,7 +1086,6 @@ protected void encodeRows(FacesContext context, DataTable table, int first, int String clientId = table.getClientId(context); List summaryRows = table.getSummaryRows(); HeaderRow headerRow = table.getHeaderRow(); - ELContext elContext = context.getELContext(); SortMeta sort = table.getHighestPriorityActiveSortMeta(); boolean encodeHeaderRow = headerRow != null && headerRow.isEnabled() && sort != null; @@ -1102,7 +1101,7 @@ protected void encodeRows(FacesContext context, DataTable table, int first, int table.setRowIndex(i); - if (encodeHeaderRow && (i == first || !isInSameGroup(context, table, i, -1, sort.getSortBy(), elContext))) { + if (encodeHeaderRow && (i == first || !isInSameGroup(context, table, i, -1, sort.getSortBy(), false))) { table.setRowIndex(i); encodeHeaderRow(context, table, headerRow); } @@ -1110,7 +1109,7 @@ protected void encodeRows(FacesContext context, DataTable table, int first, int table.setRowIndex(i); encodeRow(context, table, clientId, i, columnStart, columnEnd); - if (encodeSummaryRow && !isInSameGroup(context, table, i, 1, sort.getSortBy(), elContext)) { + if (encodeSummaryRow && !isInSameGroup(context, table, i, 1, sort.getSortBy(), i == last - 1)) { table.setRowIndex(i); encodeSummaryRow(context, summaryRows, sort); } @@ -1598,8 +1597,8 @@ protected void encodeSubTable(FacesContext context, DataTable table, SubTable su } protected boolean isInSameGroup(FacesContext context, DataTable table, int currentRowIndex, int step, ValueExpression groupByVE, - ELContext elContext) { - + boolean loadFirstRowOfNextPage) { + ELContext elContext = context.getELContext(); table.setRowIndex(currentRowIndex); Object currentGroupByData = groupByVE.getValue(elContext); @@ -1607,11 +1606,10 @@ protected boolean isInSameGroup(FacesContext context, DataTable table, int curre Object nextGroupByData; - // in case of a lazy DataTable, the LazyDataModel currently only loads rows inside the current page; we need a small hack here - // 1) get the rowData manually for the next row - // 2) put it into request-scope - // 3) invoke the groupBy ValueExpression - if (table.isLazy()) { + // An additional check is required to ensure summaryRow will be rendered in case + // number of rows of the current page is equals to the number of items in the current group (otherwise, it'll never be rendered) + // see #9077 + if (loadFirstRowOfNextPage && table.isLazy()) { Object nextRowData = table.getLazyDataModel().getRowData(nextRowIndex, table.getActiveSortMeta(), table.getActiveFilterMeta()); if (nextRowData == null) { return false; diff --git a/primefaces/src/main/java/org/primefaces/model/LazyDataModel.java b/primefaces/src/main/java/org/primefaces/model/LazyDataModel.java index c172fa7508..612bf7701d 100644 --- a/primefaces/src/main/java/org/primefaces/model/LazyDataModel.java +++ b/primefaces/src/main/java/org/primefaces/model/LazyDataModel.java @@ -107,8 +107,16 @@ public T getRowData(String rowKey) { + ", when basic rowKey algorithm is not used [component=%s,view=%s].")); } + /** + * Loads a single row for the rowIndex provided. + * + * @param rowIndex the row index to load + * @param sortBy a map with all sort information (only relevant for DataTable, not for eg DataView) + * @param filterBy a map with all filter information (only relevant for DataTable, not for eg DataView) + * @return the data + */ public T getRowData(int rowIndex, Map sortBy, Map filterBy) { - List loaded = load(rowIndex, rowIndex + 1, sortBy, filterBy); + List loaded = load(rowIndex, 1, sortBy, filterBy); if (loaded == null || loaded.isEmpty()) { return null; }