Internet resources
Implementation
to make the lazy loading works with Primefaces, you need the following components:
- xhtml view (…Lazy.xhtml): for displaying the p:dataTable lazy= »true »
- a bean, (…LazyBean.java) called by the xhtml view for building the datatable
- a class, (…LazyDataModel.java) inherited from Primefaces/LazyDataModel, called by primefaces datatable for managing the lazy loadin
- a bean interfacing the stateless ejb (…Bean.java)
- a stateless ejb, (…dao.java) for accessing the database and providing the data
Implementation example
xhtml view (…Lazy.xhtml)
<ui:fragment>
<h:form id="formMessage">
<p:growl id="messages" showDetail="true"/>
</h:form>
<p:accordionPanel id="crudPanel">
<p:tab title="Objects Traceability(Lazy loading)">
<h:form id="formTraceability">
<p:dataTable id="logTable" var="log"
value="#{applicationLogLazyBean.lazyModel}" editable="false"
paginatorTemplate="{RowsPerPageDropdown} {CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} "
paginator="true" rows="20" rowsPerPageTemplate="5,20,50" lazy="true"
tableStyle="width:auto"
>
<p:column sortBy="#{log.applicationlog.statusDate}" headerText="Date" >
<h:outputText value="#{log.applicationlog.statusDate}" >
<f:convertDateTime dateStyle="medium" timeZone="Europe/Paris" type="both" />
</h:outputText>
</p:column>
<p:column sortBy="#{log.applicationlog.eventTitle}" headerText="Event">
<h:outputText value="#{log.applicationlog.eventTitle}" />
</p:column>
<p:column sortBy="#{log.applicationlog.ownerCode}" headerText="User">
<h:outputText value="#{log.applicationlog.ownerCode}" />
</p:column>
<p:column sortBy="#{log.applicationlog.applicationName}" headerText="Appl">
<h:outputText value="#{log.applicationlog.applicationName}" />
</p:column>
<p:column headerText="Id">
<h:outputText value="#{log.webuser.id}" />
</p:column>
<p:column headerText="Shortname">
<h:outputText value="#{log.webuser.shortname}" filterBy="#{log.webuser.shortname}"/>
</p:column>
<p:column headerText="Name">
<h:outputText value="#{log.webuser.name}" filterBy="#{log.webuser.name}"/>
</p:column>
<p:column headerText="Status">
<h:outputText value="#{log.webuser.status}" />
</p:column>
<p:column headerText="Date">
<h:outputText value="#{log.webuser.statusdate}" />
</p:column>
<p:column headerText="Company">
<h:outputText value="#{log.webuser.companyid}" />
</p:column>
<p:column headerText="Type">
<h:outputText value="#{log.webuser.type}" />
</p:column>
<p:column headerText="Unit">
<h:outputText value="#{log.webuser.unitid}" />
</p:column>
<p:column headerText="Function">
<h:outputText value="#{log.webuser.function.code}" />
</p:column>
<p:column headerText="Lang.">
<h:outputText value="#{log.webuser.language}" />
</p:column>
<p:column headerText="Comment">
<h:outputText value="#{log.webuser.comment}" />
</p:column>
<f:facet name="footer">
<p:commandButton value="Refresh" update="logTable" actionListener="#{applicationLogBean.refresh}" icon="ui-icon-refresh">
<f:ajax execute="@form" render="@form" />
Number of selected events #{applicationLogBean.getTableCount()}.
</p:commandButton>
</f:facet>
</p:dataTable>
</h:form>
</p:tab>
</p:accordionPanel>
</ui:fragment>
Bean called by the xhtml view (…LazyBean.java)
package com.netricite.rbac.beans;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import org.apache.log4j.Logger;
import org.primefaces.model.LazyDataModel;
@ManagedBean
@ViewScoped
public class ApplicationLogLazyBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = -8419133227508082027L;
private static final Logger logger = Logger.getLogger( ApplicationLogLazyBean.class );
private LazyDataModel<WebuserLogView> lazyModel;
private WebuserLogView selectedEntity;
@ManagedProperty( "#{applicationLogBean}" )
private ApplicationLogBean applicationlogbean;
/**
* @return the applicationlogbean
*/
public ApplicationLogBean getApplicationlogbean() {
return applicationlogbean;
}
/**
* @param applicationlogbean
* the applicationlogbean to set
*/
public void setApplicationlogbean( ApplicationLogBean applicationlogbean ) {
this.applicationlogbean = applicationlogbean;
}
@PostConstruct
public void init() {
logger.trace( "init" );
lazyModel = new ApplicationLogLazyDataModel( applicationlogbean );
logger.trace( "init, LazyModel created" );
}
public LazyDataModel<WebuserLogView> getLazyModel() {
return lazyModel;
}
public WebuserLogView getSelectedEntity() {
return selectedEntity;
}
public void setSelectedEntity( WebuserLogView selectedEntity ) {
this.selectedEntity = selectedEntity;
}
}
Class inherited from LazyDataModel, (…LazyDataModel.java)
package com.netricite.rbac.beans;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
public class ApplicationLogLazyDataModel extends LazyDataModel<WebuserLogView> {
/**
*
*/
private static final long serialVersionUID = 7723480065915105372L;
private static final Logger logger = Logger.getLogger( ApplicationLogLazyDataModel.class );
private List<WebuserLogView> datasource;
// public ApplicationLogLazyDataModel( List<WebuserLogView> datasource ) {
// this.datasource = datasource;
// }
private final ApplicationLogBean daoService;
public ApplicationLogLazyDataModel( ApplicationLogBean daoService ) {
this.daoService = daoService;
}
@Override
public WebuserLogView getRowData( String rowKey ) {
for ( WebuserLogView event : datasource ) {
if ( event.getApplicationlog().getShortName().equals( rowKey ) ) {
return event;
}
}
return null;
}
@Override
public Object getRowKey( WebuserLogView event ) {
return event.getApplicationlog().getShortName();
}
@Override
public List<WebuserLogView> load( int first, int pageSize, String sortField, SortOrder sortOrder,
Map<String, Object> filters ) {
logger.trace( "load" );
daoService.refresh( first, pageSize );
datasource = daoService.refresh( daoService.getEntities() );
setRowCount( daoService.getTableCount() );
return datasource;
}
}
Bean for interfacing the stateless ejb(dao) (…Bean.xhtml)
Refresh the data used for creating the datasource of the lazyDataModel
/*
* refresh the datable bean
*/
public void refresh( int rowPosition_arg, int pageSize_arg ) {
logger.trace( "Refresh/Entities position(" + getRowPosition() + ")" );
entities = entitydao.findAll( rowPosition_arg, pageSize_arg );
listlength = entities.size();
logger.trace( "Refresh/#Entities(" + listlength + ")" );
logs = refresh( entities );
}
Refresh the data to be stored in the datasource object of the …LazyModel
/*
* Create a list of events relative to the selected objects
*/
public List refresh(
List entities_arg ) {
List events = new ArrayList();
// Load list of events (applicationLog + Associated webuser)
for ( ApplicationLog applicationlog : entities_arg ) {
WebuserLogView obj = new WebuserLogView( applicationlog );
if ( obj.getWebuser() != null ) {
events.add( obj );
}
}
listlength = events.size();
logger.trace( "Refresh/#logs(" + listlength + ")" );
return events;
}
Stateless ejb for accessing the database (…DAO.java)
/**
* SELECT COUNT(*) FOR applicationlog;
*
* @return count
*/
public int countAll() {
Query query = entitymanager.createNamedQuery( "ApplicationLog.countAll" );
Number count = 0;
try {
count = (Number) query.getSingleResult();
} catch ( Exception e ) {
throw new DAOexception( e );
}
return count.intValue();
}
/**
* SELECT * FROM table SORTED BY code
*
* @return list of entity
*/
public List<ApplicationLog> findAll( int rowPosition_arg, int pageSize_arg ) throws DAOexception {
TypedQuery<ApplicationLog> query =
entitymanager.createNamedQuery( "ApplicationLog.findAll", ApplicationLog.class )
.setMaxResults( pageSize_arg );
query.setFirstResult( rowPosition_arg );
return query.getResultList();
}
Tips
- see code example and internet link resources
- easy to implement, nevertheless the documention related to connection pool is weak, see my implementation
- The main issue is to get the required datasource and count in the …LazyDataModel which is specific to your ownn implementation
- the …LazyDataModel constructor is used to provide the reference of the object which is in charge of accessing the database
- Tehn everything is straigth forward, you just need to access the data based on the previous object
Next steps