I'm using PrimeFaces 5 on Tomcat 7.
I'm using the p:dataTable component with Lazy Loading implementation and pagination feature.
I'm facing the following problem:
- if the number of rows in the resultSet is too high (for instance starting from 10 millions of rows), the query gets executed but the browser blocks (tested both on Chrome and Mozilla) and is not able to display the data-table data.
I did also the following tests:
- I set a fake small total count in the lazy loading implementation and this time the browser was able to show the result;
- I put fake high total count on those tables that have a limited number of rows and that were displayed without problems, and this time again the browser blocked and was not able to show the results anymore;
Here is the code:
- .xhtml
Code: Select all
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Web client</title>
</h:head>
<h:body>
<h:form id="mainform">
<p:dataTable widgetVar="dataTableWidgetVar" draggableColumns="true"
scrollable="true" scrollWidth="100%" scrollHeight="300" var="row"
value="#{queryResultBean.lazyModel}" paginator="true" id="table"
sortMode="multiple"
paginatorTemplate="Display {RowsPerPageDropdown} item(s) {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink} Go to page {JumpToPageDropdown}"
currentPageReportTemplate="{startRecord}-{endRecord} out of {totalRecords} item(s)"
paginatorPosition="both" rowsPerPageTemplate="20,50,100,300,500"
rows="#{queryResultBean.selectionsToPost.getQueriesGeneralOptions().limit}"
styleClass="data-table" lazy="true" rowIndexVar="rowIndex">
<!--Start of Table Header -->
<f:facet name="header">
<h:outputText value="Result Table" />
</f:facet>
<!--End of Table Header -->
<!-- Row values extraction -->
<p:column headerText="#">
<h:outputText value="#{row.number}" />
</p:column>
<c:forEach
items="#{queryResultBean.rows.get(rowIndex % queryResultBean.selectionsToPost.getQueriesGeneralOptions().limit).attributesGroup}"
var="attrGrpValues">
<c:forEach items="#{attrGrpValues.attribute}" var="attrValues">
<p:column style="width: -moz-max-content;"
headerText="#{attrGrpValues.alias == null ? attrGrpValues.name : attrGrpValues.alias } #{attrValues.name}">
<h:outputLink target="_blank" value="#{attrValues.link}"
id="cell-element" disabled="#{attrValues.link == null}">
<h:outputText value="#{attrValues.value}" />
</h:outputLink>
</p:column>
</c:forEach>
</c:forEach>
</p:dataTable>
</h:form>
</h:body>
</html>
Code: Select all
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.Flash;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortMeta;
@ManagedBean
@ViewScoped
public class QueryResultBean implements Serializable {
private final static Logger logger = LoggerFactory
.getLogger(QueryResultBean.class);
private static final long serialVersionUID = 1L;
private boolean aliasNeeded = false;
private LazyDataModel<RowType> lazyModel;
protected List<RowType> rows;
protected FeatureDetails selectionsToPost = new FeatureDetails();
private String limit;
private int contatore = 1;
@PostConstruct
public void init() {
// GET USER SELECTIONS
FacesContext context = FacesContext.getCurrentInstance();
ExternalContext extContext = context.getExternalContext();
Flash flash = context.getExternalContext().getFlash();
// EXTRACT QUERY GENERAL OPTIONS
QueryGeneralOption genOpt = (QueryGeneralOption) flash.get("genOp");
//set all user specified selections that will be posted to a service
selectionsToPost.add(...);
rows = null;
lazyModel = new MyLazyDataModel(this);
}
public List<RowType> getRows() {
if (rows == null) {
List<SortMeta> multiSortMeta = new ArrayList<SortMeta>();
Map<String, Object> filters = new HashMap<String, Object>();
lazyModel.load(0, Integer.valueOf(selectionsToPost.getQueriesGeneralOptions().getLimit()), multiSortMeta, filters);
}
return rows;
}
public void setRows(List<RowType> rows) {
this.rows = rows;
}
public LazyDataModel<RowType> getLazyModel() {
return lazyModel;
}
public FeatureDetails getSelectionsToPost() {
return selectionsToPost;
}
}
Code: Select all
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortMeta;
public class MyLazyDataModel extends LazyDataModel<RowType> {
private static final long serialVersionUID = 1L;
private int totalRowCount = 0;
private List<SortMeta> multiSortMeta = new ArrayList<SortMeta>();
//Map<String, Object> filters = new HashMap<String, Object>();
private List<RowType> data = null;
private int first = 0;
private QueryResultBean queryResultBean ;
public MyLazyDataModel(QueryResultBean queryResultBean) {
super();
this.queryResultBean = queryResultBean;
}
@Override
public List<RowType> load(int first, int pageSize,
List<SortMeta> multiSortMeta, Map<String, Object> filters) {
FeatureDetails selectionsToPost = queryResultBean.selectionsToPost;
data = new ArrayList<RowType>();
Client4_RESTCalls client = new Client4_RESTCalls();
//SETTING PAGINATION OPTIONS
selectionsToPost.getQueriesGeneralOptions().setLimit(String.valueOf(pageSize));
selectionsToPost.getQueriesGeneralOptions().setOffset(String.valueOf(first));
//QUERY RESULT
PublicDataDetails queryResult = client.getQueryResult(selectionsToPost);
data = queryResult.getTableResult().get(0).getRowsGroup().getRow();
int pageOffset = Integer.parseInt(selectionsToPost.getQueriesGeneralOptions().getOffset());
if(!data.isEmpty()){
if(queryResult.getTableResult().get(0).getEntriesTotalCount().getExactCount()!=null) {
totalRowCount = Integer.valueOf(queryResult.getTableResult().get(0).getEntriesTotalCount().getExactCount());
}else{
totalRowCount= Integer.valueOf(queryResult.getTableResult().get(0).getEntriesTotalCount().getEstimatedCount());
}
multiSortMeta = new ArrayList<SortMeta>();
filters = new HashMap<String, Object>();
this.setRowCount(totalRowCount);
queryResultBean.rows = data;
}
return data;
}
public List<RowType> getData() {
return data;
}
public void setData(List<RowType> data) {
this.data = data;
}
}