#ViewScoped is recreated after button action on WebLogic - jsf

First of all I know some other similar questions about my title, but My issue is a little bit different... When I try to initialize LazyDataModel in my #ViewScoped Bean it works fine until I click the actionButton on my page. When My Bean is created, its #PostConstruct method works as expected and LazyDataModel filled up in that method then datatable populated well. But when ajax called by actionButton in my page then entire bean recreated and #PostConstruct method called again, with that LazyDataModel value changing to null. Because of that, my page is crashing. In another scenario I was using rowSelect event in my datatable instead of actionButton with method which has a SelectEvent parameter. In SelectEvent parameter object field of it was null and I was getting NullPointerException. These are the scenarios... As result I guess when I use LazyDataModel in my #ViewScoped bean It calls PostConstruct again and my datamodel returns null for my SelectEvent method.
This is my ViewScoped PostConstruct method
#ManagedBean (name = "myEctrInboxBB")
#ViewScoped
public class MyEContractInboxBackingBean implements Serializable {
private static final long serialVersionUID = 2399679621562918360L;
private static final Logger logger = LogManager.getLogger(MyEContractInboxBackingBean.class);
#ManagedProperty("#{ectrDomainService}")
EContractDomainService ectrDomainService;
#ManagedProperty("#{eContractUtil}")
EContractUtilBean eContractUtil;
#ManagedProperty("#{ectrApproveController}")
EContractApproveControllerBean ectrApproveController;
private EContractInboxItem selectedInboxRow;
private LazyEContractInboxItemModel lazyEcontractInboxItem;
private List<EContractInboxItem> inboxItems = new ArrayList<EContractInboxItem>();
private List<EContractInboxItem> filteredInboxItems = new ArrayList<EContractInboxItem>();
#PostConstruct
public void init() {
User portalUser = getUser();
List<String> userRoles = fetchUserRoles(portalUser);
List<String> userSmCodes = fetchUserSmCodes(userRoles, portalUser);
lazyEcontractInboxItem = new LazyEContractInboxItemModel(ectrDomainService, eContractUtil, userRoles, userSmCodes);
}
public void onRowSelect(SelectEvent selectEvent) {
logger.info("**************************" + selectEvent);
}
public void openSelectedJob(EContractInboxItem item) {
ectrApproveController.openEContractInfoPage(item.getProcessInstanceId());
}
LazyDataModel
public class LazyEContractInboxItemModel extends LazyDataModel<EContractInboxItem>{
List<EContractInboxItem> inboxItems = new ArrayList<EContractInboxItem>();
List<Task> taskList = new ArrayList<Task>();
EContractDomainService ectrDomainService;
EContractUtilBean ectrUtilBean;
List<String> userRoles = new ArrayList<String>();
List<String> userSmCodes = new ArrayList<String>();
public LazyEContractInboxItemModel(EContractDomainService ectrDomainService, EContractUtilBean utilBean, List<String> roles,
List<String> smCodes) {
userRoles.addAll(roles);
userSmCodes.addAll(smCodes);
ectrUtilBean = utilBean;
this.ectrDomainService = ectrDomainService;
}
public List<EContractInboxItem> getInboxItems() {
return inboxItems;
}
public void setInboxItems(List<EContractInboxItem> inboxItems) {
this.inboxItems = inboxItems;
}
#Override
public List<EContractInboxItem> load(int first, int pageSize, String sortField, SortOrder sortOrder,
Map<String, Object> filters) {
taskList = ectrDomainService.findTaskListAssignedToUserByUser(userRoles, userSmCodes);
inboxItems.clear();
inboxItems.addAll(ectrUtilBean.retrieveInboxItems(taskList));
setRowCount(inboxItems.size());
return inboxItems;
}
#Override
public List<EContractInboxItem> load(int first, int pageSize, List<SortMeta> multiSortMeta,
Map<String, Object> filters) {
taskList = ectrDomainService.findTaskListAssignedToUserByUser(userRoles, userSmCodes);
inboxItems.clear();
inboxItems.addAll(ectrUtilBean.retrieveInboxItems(taskList));
setRowCount(inboxItems.size());
return inboxItems;
}
#Override
public Object getRowKey(EContractInboxItem object) {
return object.getProcessInstanceId();
}
#Override
public EContractInboxItem getRowData() {
return super.getRowData();
}
#Override
public EContractInboxItem getRowData(String rowKey) {
for (EContractInboxItem eContractInboxItem : inboxItems) {
if (rowKey.equals(eContractInboxItem.getProcessInstanceId()))
return eContractInboxItem;
}
return null;
}
getters and setters
xhtml page with actionButton
<?xml version="1.0"?>
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:pe="http://primefaces.org/ui/extensions">
<h:form
id="eContractWaitingApprovalForm"
prependId="false"
enctype="multipart/form-data">
<p:messages id="topmsgForEcontractWaitingApproval" />
<div class="ui-grid ui-grid-responsive">
<p:dataTable
id="waitingEcontracts"
widgetVar="waitingEcontracts"
styleClass="grid-sm-bottom"
rows="20"
resizableColumns="true"
resizeMode="expand"
paginator="true"
lazy="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15,50,100,200"
value="#{myEctrInboxBB.lazyEcontractInboxItem}"
var="item">
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agreement.no']}">
<h:outputText value="#{item.eContract.eContractCode}" />
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agreement.subject']}">
<h:outputText value="#{item.eContract.eContractSubject}" />
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agreement.date']}">
<h:outputText value="#{item.eContract.eContractDate}">
<f:convertDateTime
type="date"
pattern="dd-MM-yyyy" />
</h:outputText>
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agency.name']}">
<h:outputText value="#{item.agencyName}" />
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agency.type']}">
<h:outputText value="#{item.agencyType}" />
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agency.sales.manager']}">
<h:outputText
value="#{myEctrInboxBB.findSalesOfficeBySmCode(item.agencySM)}" />
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agreement.status']}">
<h:outputText
value="#{item.eContract.eContractStatus eq 'INPROGRESS' ? i18n['e-contract.dt.waiting.inprogress'] : item.eContract.eContractStatus}" />
</p:column>
<p:column styleClass="center-column">
<p:commandButton
process="#this"
icon="ui-icon-search"
value="#{i18n['e-contract.dt.waiting.see.detail']}"
action="#{myEctrInboxBB.openSelectedJob(item)}" />
</p:column>
</p:dataTable>
</div>
</h:form>
xhtml page with rowSelect
<?xml version="1.0"?>
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:pe="http://primefaces.org/ui/extensions">
<h:form
id="eContractWaitingApprovalForm"
prependId="false"
enctype="multipart/form-data">
<p:messages id="topmsgForEcontractWaitingApproval" />
<div class="ui-grid ui-grid-responsive">
<p:dataTable
id="waitingEcontracts"
widgetVar="waitingEcontracts"
styleClass="grid-sm-bottom"
rows="20"
resizableColumns="true"
resizeMode="expand"
paginator="true"
lazy="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15,50,100,200"
value="#{myEctrInboxBB.lazyEcontractInboxItem}"
var="item"
selection="#{myEctrInboxBB.selectedInboxRow}"
selectionMode="single"
rowKey="#{item.processInstanceId}">
<p:ajax event="rowSelect" listener="#{myEctrInboxBB.onRowSelect}"/>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agreement.no']}">
<h:outputText value="#{item.eContract.eContractCode}" />
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agreement.subject']}">
<h:outputText value="#{item.eContract.eContractSubject}" />
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agreement.date']}">
<h:outputText value="#{item.eContract.eContractDate}">
<f:convertDateTime
type="date"
pattern="dd-MM-yyyy" />
</h:outputText>
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agency.name']}">
<h:outputText value="#{item.agencyName}" />
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agency.type']}">
<h:outputText value="#{item.agencyType}" />
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agency.sales.manager']}">
<h:outputText
value="#{myEctrInboxBB.findSalesOfficeBySmCode(item.agencySM)}" />
</p:column>
<p:column
styleClass="center-column"
headerText="#{i18n['e-contract.dt.waiting.agreement.status']}">
<h:outputText
value="#{item.eContract.eContractStatus eq 'INPROGRESS' ? i18n['e-contract.dt.waiting.inprogress'] : item.eContract.eContractStatus}" />
</p:column>
</p:dataTable>
</div>
</h:form>
When I clicked a row of Datatable selectEvent.getObject() --> NULL always with LazyDataModel.
A big important information: These all situations happens in WebLogic 10.3.6.0 and works on TomCat like charm (even with LazyDataModel).
My Development environment: JSF 2.0, Primefaces 5.2, Liferay 6.2.3 ga4 with TomCat 7.04.
Testing environment: Same all except WebLogic 10.3.6.0 (Problem only occurs on here)
I really appreciate if someone could help me... Thanks in advance!!!
EDIT:
#ManagedBean (name = "myEctrInboxBB")
#ViewScoped
public class MyEContractInboxBackingBean implements Serializable {
private static final long serialVersionUID = 2399679621562918360L;
private static final Logger logger = LogManager.getLogger(MyEContractInboxBackingBean.class);
#ManagedProperty("#{ectrDomainService}")
private transient EContractDomainService ectrDomainService;
#ManagedProperty("#{eContractUtil}")
private EContractUtilBean eContractUtil;
#ManagedProperty("#{ectrApproveController}")
private EContractApproveControllerBean ectrApproveController;
private EContractInboxItem selectedInboxRow;
private LazyEContractInboxItemModel lazyEcontractInboxItem;
#PostConstruct
public void init() {
User portalUser = getUser();
List<String> userRoles = fetchUserRoles(portalUser);
List<String> userSmCodes = fetchUserSmCodes(userRoles, portalUser);
lazyEcontractInboxItem = new LazyEContractInboxItemModel(userRoles, userSmCodes);
}
We can access Spring Beans like that:
public EContractProcessService geteContractProcessService() {
ELContext elContext = FacesContext.getCurrentInstance().getELContext();
return (EContractProcessService) FacesContext.getCurrentInstance().getApplication()
.getELResolver().getValue(elContext, null, "eContractProcessService");
}

Related

Primefaces Lazytable, using one Bean for different filter criterias

I have a Bean which returns "Notes" for different entities.
E.g. I can have Notes for Offers, Customers, Invoice etc.
Instead of creating many beans for the different entities, I want to have one Bean which returns die correct Notes for each entity. I´ve send in my JSF page the two information "entityType" and "objectId" to the bean. With this two parameters, I can filter my datatable in the bean
Currently I have the following code, in this example for "OFFER":
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:pe="http://primefaces.org/ui/extensions"
template="/WEB-INF/layout/portal/template.xhtml"
xmlns:o="http://omnifaces.org/ui"
xmlns:of="http://omnifaces.org/functions">
<ui:define name="head" />
<ui:define name="title">Page</ui:define>
<ui:define name="content">
<p:growl id="growl" showDetail="false" sticky="false" life="3000" />
<div class="ui-g">
<div class="ui-g-12">
<div class="card card-w-title">
<p:tabView id="offerTab" dynamic="true" cache="false"
widgetVar="tabPanel">
<p:tab id="note"
disabled="#{offerEditController.modeOffer eq 'ADD'}">
<f:facet name="title">
<i class="fa fa-sticky-note Fs12 MarRight40"></i>
<h:outputText value=" Notizen" />
</f:facet>
<div class="EmptyBox10"></div>
<p:outputPanel id="notePanel">
<div class="ui-g ui-fluid">
<div class="ui-g-12 ui-lg-5">
<h:form id="noteForm"
rendered="#{noteRequestByObjectController.init('OFFER', offerEditController.offer.id, offerEditController.offer.idHash)}">
<p:dataTable id="noteListDatatable"
value="#{noteRequestByObjectController.lazyModel}"
var="note" widgetVar="noteTable" resizableColumns="false"
multiViewState="false" selectionMode="single"
selection="#{noteRequestByObjectController.selectedNote}"
filteredValue="#{noteRequestByObjectController.filteredNote}"
rows="50" pageLinks="10" paginatorPosition="bottom"
lazy="true" paginator="true" reflow="true"
currentPageReportTemplate="(Eintrag: {startRecord}-{endRecord} von {totalRecords}, Seite: {currentPage} von {totalPages})"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="50,100,200"
paginatorAlwaysVisible="false"
emptyMessage="Kein Eintrag gefunden">
<f:facet name="header">
<p:outputPanel id="functionalityPanel"
style="float:left; margin-top: -3px">
<p:commandButton value="Neu hinzufügen"
styleClass="green-btn White" icon="fa fa-plus-circle"
actionListener="#{noteRequestByObjectController.doCreateNew}"
update=":offerTab:noteForm:noteListDatatable, :offerTab:addNoteForm"
resetValues="true" ajax="true">
</p:commandButton>
</p:outputPanel>
<h:outputText id="overviewText"
value="Übersicht (#{noteRequestByObjectController.numberTotal})" />
<p:tooltip for="overviewText" position="top"
value="Die Gesamtzahl der Filterung" />
</f:facet>
<p:ajax event="rowSelect" ajax="true" immediate="true"
resetValues="true"
listener="#{noteRequestByObjectController.onSelectNote}"
update=":offerTab:noteForm, :offerTab:addNoteForm" />
<p:column sortBy="#{note.createDate}" visible="true">
<f:facet name="header">
<h:outputText value="Create" />
</f:facet>
<h:outputText id="createDateInfo"
style="margin-left: 5px;" value="#{note.createDate}"
styleClass="Fright">
<f:converter converterId="prettyTimeCustomConverter" />
</h:outputText>
</p:column>
</p:dataTable>
</h:form>
</div>
</div>
</p:outputPanel>
<div class="EmptyBox20"></div>
</p:tab>
</p:tabView>
</div>
</div>
</div>
</ui:define>
My Bean:
- Contains the init function and the function for loading the Notes from Database:
#ViewScoped
#Named
public class NoteRequestByObjectController extends LazyDataModel<Note>
implements SelectableDataModel<Note>, Serializable {
private static final long serialVersionUID = 2815796004558360299L;
private final Logger LOGGER = LoggerFactory.getLogger(NoteRequestByObjectController.class);
#EJB
private NoteService noteService;
#Inject
private LoginBean loginBean;
private List<Note> filteredNote;
private List<Note> selectedNoteList = new ArrayList<Note>();
private LazyDataModel<Note> lazyModel;
private List<Note> list;
private Note selectedNote;
private List<Boolean> toogleList;
private List<ObjectForSearchList> searchList = new ArrayList<ObjectForSearchList>();
private int numberTotal = 0;
public enum ModeNote {
EDIT, ADD
};
private ModeNote mode;
private String entityType;
private String visibleType;
private Long objectId;
private String objectIdHash;
private boolean startLoad = false;
/**
* Init
*/
public boolean init(String currentEntityType, Long currentObjectId, String currentObjectIdHash) {
try {
entityType = currentEntityType;
objectId = currentObjectId;
objectIdHash = currentObjectIdHash;
if (objectId == null || objectIdHash == null)
return true;
lazyModel = null;
// SearchList
initSearchList();
findNote();
selectedNote = new Note();
mode = ModeNote.ADD;
startLoad = true;
LOGGER.info("END init");
return true;
}
catch (Exception e) {
LOGGER.error(ExceptionUtils.getFullStackTrace(e));
}
return false;
}
/**
* Die eigentliche Suche
*/
public void findNote() {
LOGGER.info("START findNote");
lazyModel = null;
if (lazyModel == null) {
lazyModel = new LazyDataModel<Note>() {
#Override
public List<Note> load(int startingAt, int maxPerPage, String sortField, SortOrder sortOrder,
Map<String, Object> filters) {
try {
list = noteService.findAllNoteLazyLoading(searchList, startingAt, maxPerPage, sortField,
sortOrder, filters);
numberTotal = noteService.countNoteRowsLazyLoading(searchList);
lazyModel.setRowCount(numberTotal);
} catch (NoteNotFoundException e) {
lazyModel.setRowCount(0);
numberTotal = 0;
} catch (Exception e) {
lazyModel.setRowCount(0);
numberTotal = 0;
}
return list;
}
#Override
public Note getRowData(String rowKey) {
if (list != null && !list.isEmpty())
for (Note note : list) {
String s = "Note [id=" + note.getId() + "]";
if (s.equals(rowKey))
return note;
}
return null;
}
#Override
public Object getRowKey(Note note) {
return note;
}
};
}
}
The code is working and I got for each different Entity and his ID the correct Notes for this object.
But my problem is, if I have a look in the Log. The init() function is calling multiple times.
Is there any possible solution for that scenario to avoid to have many Beans for each Entity (Customer, Offer, Invoice etc. etc.)
Many thanks
You have your init method on the rendered attribute of the form, so every time that JSF evaluates if the form needs to be rendered it calls the init method.
You could put your init method in a viewAction, something like this:
<f:view ....>
<f:metadata>
<f:viewAction action="#{noteRequestByObjectController.init('OFFER', offerEditController.offer.id, offerEditController.offer.idHash)}"/>
</f:metadata>

Primefaces datatable LazyDataModel create new row

I have a primefaces datatable which uses LazyDataModel instead Collection.
I need to implement a button which create a new row in the table (empty row in last row of actual page in datatable).
I have tried adding.
#Component("table")
#Scope("session")
public class TablaPaginada implements Serializable {
private LazyDataModel<User> users;
#PostConstruct
private void init() {
usuarios = new LazyDataModel<User>() {
private static final long serialVersionUID = 8885722005055879976L;
#Override
public List<User> load(int first, int pageSize, String sortField,
SortOrder sortOrder, Map<String, Object> filters) {
List<User> data = getUsers(first, pageSize, sortOrder, filters);
return data;
}
};
users.setRowCount(totalRowUsers());
}
public void newRow() {
//I would do this if it was List instead LazyDataModel
//this.users.add(new User());
users.getWrappedData().add(new User()); //this does not work.
}
}
This would be the xhtml code:
<h:form>
<p:dataTable rowsPerPageTemplate="5,10,15" value="#{table.users}" var="user" paginator="true"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
rows="5" lazy="true">
<p:column headerText="id" sortBy="#{user.id}" filterBy="#{user.id}">
<h:outputText value="#{user.id}" />
</p:column>
<p:column headerText="name" sortBy="#{user.name}" filterBy="#{user.name}">
<h:outputText value="#{user.name}" />
</p:column>
<p:column headerText="lastName" sortBy="#{user.lastName}" filterBy="#{user.lastName}">
<h:outputText value="#{user.lastName}" />
</p:column>
<p:column headerText="money" sortBy="#{user.money}" filterBy="#{user.money}">
<h:outputText value="#{user.money}" />
</p:column>
</p:dataTable>
<p:commandButton value="new row" action="#{table.newRow()}" update="#form"/>
</h:form>
EDIT:
my code does not create new row.
From PF documentation: <p:commandButton value="Add" actionListener="#{dtBasicView.addCar}"
oncomplete="PF('dt').addRow()" process="#this"/>
And for Lazy Datatable you may run into this issue which has a workaround: https://github.com/primefaces/primefaces/issues/3901

CommandButton in Dialog containing Picklist doesn't fire action method

the problem I have is that the command button in my dialog doesn't fire the action method in the controller. No logger outputs for the example method "greet". Can anybody look over please and give me hints? What am I doing wrong?
My JSF-Page:
<!DOCTYPE HTML>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui" xmlns:o="http://omnifaces.org/ui"
xmlns:of="http://omnifaces.org/functions">
<f:view id="bestellungLieferantView">
<f:metadata>
<f:event type="preRenderView"
listener="#{camundaTaskForm.startTaskForm()}" />
</f:metadata>
<h:head>
<title>Paket zusammenstellen</title>
</h:head>
<h:body>
<h:form id="bestellungLieferantForm">
<p:dialog id="komponentenAuswahlDialog"
header="Komponenten auswählen" widgetVar="komponentenAuswahlDialog"
modal="true" height="auto" width="auto">
<p:pickList id="komponenteAuswahlPickList"
value="#{bestellungLieferantController.komponentenDualListModel}"
var="komponente" itemLabel="#{komponente.serienNummer}"
converter="entityConverter"
itemValue="#{komponente}" showSourceFilter="true"
showTargetFilter="true">
<f:facet name="sourceCaption">Quelle</f:facet>
<f:facet name="targetCaption">Ziel</f:facet>
</p:pickList>
<p:commandButton process="#this"
action="#{bestellungLieferantController.greet}"
id="auswahlSpeichern" value="Auswahl speichern"
oncomplete="PF('komponentenAuswahlDialog').hide();" />
</p:dialog>
<h:panelGrid id="paketInformationPG" columns="2" border="1">
<f:facet name="header">
<h:outputText value="Paket zusammenstellen" />
</f:facet>
<h:outputLabel value="Kunde:" />
<h:outputText value="#{processVariables['kunde']}" />
<h:outputLabel value="Betriebssystem:" />
<h:outputText value="Platzhalter" />
<h:outputLabel value="Benutzer:" />
<h:outputText value="#{processVariables['benutzerName']}" />
</h:panelGrid>
<h:panelGrid id="komponentenZusammenstellungPG" columns="2"
border="1">
<f:facet name="header">
<h:panelGrid columns="2">
<h:outputText value="Komponenten" />
<p:commandButton id="auswahlKomponenteButton"
action="#{bestellungLieferantController.createAvailableKomponentDualListModel()}"
type="button" onclick="PF('komponentenAuswahlDialog').show();"
value="+" />
</h:panelGrid>
</f:facet>
<p:dataTable id="komponenteTable" widgetVar="komponenteTable"
var="komponente"
value="#{bestellungLieferantController.komponentenList}">
<p:column>
<f:facet name="header">Typ</f:facet>
<h:outputText value="#{komponente.produkt.typ.name}" />
</p:column>
<p:column>
<f:facet name="header">Bezeichnung</f:facet>
<h:outputText value="#{komponente.produkt.name}" />
</p:column>
<p:column>
<f:facet name="header">SN</f:facet>
<h:outputText value="#{komponente.serienNummer}" />
</p:column>
<p:column headerText="Kaufdatum">
<f:facet name="header">Kaufdatum</f:facet>
<h:outputText value="#{komponente.bestellDatum}" />
</p:column>
<p:column>
<f:facet name="header">Aktion</f:facet>
<p:commandLink value="Bearbeiten" />
<p:commandLink value="Enfernen" />
</p:column>
</p:dataTable>
</h:panelGrid>
</h:form>
</h:body>
</f:view>
</html>
My Bean:
#ManagedBean(name="bestellungLieferantController")
#SessionScoped
public class BestellungLieferantController implements Serializable{
/**
*
*/
private static final long serialVersionUID = 2862985625231368306L;
#EJB
private BestellungFacade bestellungFacade;
#EJB
private PaketFacade paketFacade;
#EJB
private KomponenteFacade komponenteFacade;
#EJB
private BetriebssystemFacade betriebssystemFacade;
// Komponent-List with added komponent items
private List<Komponente> komponentenList = new ArrayList<Komponente>();
private DualListModel<Komponente> komponentenDualListModel;
private static final Logger logger = Logger.getLogger(BestellungLieferantController.class);
public DualListModel<Komponente> getKomponentenDualListModel() {
return komponentenDualListModel;
}
public void setKomponentenDualListModel(DualListModel<Komponente> komponentenDualListModel) {
this.komponentenDualListModel = komponentenDualListModel;
}
public List<Komponente> getKomponentenList() {
logger.info("KomponenList-Size: " + this.komponentenList.size());
return komponentenList;
}
public void setKomponentenList(List<Komponente> komponentenList) {
logger.info("Setting a new KomponentenList...");
this.komponentenList = komponentenList;
}
public void greet(){
logger.info("Greet Method Invoked!");
}
/**
* Gets the actual Model with the distinct source and
* #param targetList
* #return
*/
#PostConstruct
public void createAvailableKomponentDualListModel(){
// Logger
logger.info("CreateAvailableKomponentDualList invoked!");
List<Komponente> sourceKomponenteList = this.komponenteFacade.getAllAvailableKomponente();
List<Komponente> sourceKomponenteDistinctList = new ArrayList<Komponente>();
if (this.komponentenList.size() != 0){
for(Komponente k : sourceKomponenteList){
if (!komponentenList.contains(k)){
sourceKomponenteDistinctList.add(k);
}
}
} else {
sourceKomponenteDistinctList = sourceKomponenteList;
}
// komponentenDualListModel.setSource(sourceKomponenteDistinctList);
// komponentenDualListModel.setTarget(komponentenList);
this.setKomponentenDualListModel(new DualListModel<Komponente>());
this.getKomponentenDualListModel().setSource(sourceKomponenteDistinctList);
this.getKomponentenDualListModel().setTarget(this.komponentenList);
}
public void putSelectionIntoKomponenteList(){
logger.info("PutSelectionIntoKomponentList");
logger.info("KOMPONENTELIST: " + komponentenDualListModel.getTarget());
this.komponentenList = this.komponentenDualListModel.getTarget();
}
}
My Converter:
#FacesConverter(value = "entityConverter")
public class EntityConverter implements Converter {
// Checking the converter
private static final Logger logger = Logger.getLogger(EntityConverter.class);
private static Map<Object, String> entities = new WeakHashMap<Object, String>();
#Override
public String getAsString(FacesContext context, UIComponent component, Object entity) {
synchronized (entities) {
logger.info("[Converter] GetAsString: " + ", Class:" + entity.getClass() + ", Component-ID: " + component.getId());
if (!entities.containsKey(entity)) {
String uuid = UUID.randomUUID().toString();
entities.put(entity, uuid);
return uuid;
} else {
return entities.get(entity);
}
}
}
#Override
public Object getAsObject(FacesContext context, UIComponent component, String uuid) {
logger.info("[Converter] GetAsString: " + ", UUID:" + uuid + ", Component-ID: " + component.getId());
for (Entry<Object, String> entry : entities.entrySet()) {
if (entry.getValue().equals(uuid)) {
return entry.getKey();
}
}
//return uuid;
return null;
}
}
you need actionListener attribute instead of action in your p:commandbutton tag. and Also use #ViewScoped instead of #SessionScoped in your backing bean. and add ajax="false" in p:commandButton

PrimeFaces DataTable lazy loading is loaded twice

The problem is that overridden method load() in my LazyDataModel implementation is being called twice every time I try to filter the table.
My LazyDataModel implementation:
public class LazyPostDataModel extends LazyDataModel<Post> {
private List<Post> data;
private final PostService postService;
public LazyPostDataModel(PostService postService) {
this.postService = postService;
data = new ArrayList<>();
}
#Override
public Post getRowData(String rowKey) {
Long id = Long.valueOf(rowKey);
for (Post p : data) {
if (p.getId().equals(id))
return p;
}
return null;
}
#Override
public Object getRowKey(Post post) {
return post.getId();
}
#Override
public List<Post> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,Object> filters) {
PostFilter filter = new PostFilter(filters, first, pageSize);
FilteredDataModel<Post> postDataModel = postService.findFilteredList(filter);
data = postDataModel.getData();
this.setRowCount(postDataModel.getCount().intValue());
return data;
}
}
My xhtml View:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<ui:composition>
<p:panel header="Posts to Review">
<ui:include src="ModerationPostContextMenu.xhtml" />
<p:dataTable id="ModerationPostTable" value="# {moderationPostController.posts}" var="post" lazy="true" rows="25" widgetVar="ModerationPostTable"
paginator="true" rowKey="#{post.id}" selectionMode="single" selection="#{moderationPostController.selected}"
paginatorTemplate="{FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" >
<p:ajax event="rowSelect" update="#form:contextMenu" />
<p:ajax event="rowUnselect" update="#form:contextMenu" />
<p:column headerText="Id">
<h:outputText value="#{post.id}"/>
</p:column>
<p:column headerText="Creation Date">
<h:outputText value="#{post.creationDate}"/>
</p:column>
<p:column headerText="Author Id">
<h:outputText value="#{post.author.id}"/>
</p:column>
<p:column headerText="Author Nickname">
<h:outputText value="#{post.author.nickname}"/>
</p:column>
<p:column headerText="Text">
<h:outputText value="#{post.text}" />
</p:column>
<p:column headerText="Media" width="200">
<p:graphicImage value="#{mediaController.buildUrl(post.media)}"
width="200" height="200"/>
</p:column>
<p:column headerText="Status" filterBy="#{post.moderationApproved}">
<f:facet name="filter">
<p:selectOneButton onchange="PF('ModerationPostTable').filter()">
<f:converter converterId="javax.faces.Boolean" />
<f:selectItem itemLabel="Approved" itemValue="true" />
<f:selectItem itemLabel="Rejected" itemValue="false" />
<f:selectItem itemLabel="Review" itemValue="" />
</p:selectOneButton>
</f:facet>
<h:outputText value="#{post.moderationApproved}" />
</p:column>
</p:dataTable>
</p:panel>
</ui:composition>
</html>
And the controller
#Named("moderationPostController")
#SessionScoped
#Transactional(Transactional.TxType.REQUIRED)
public class ModeratioPostController extends BaseController implements Serializable {
#Inject PostService postService;
private LazyPostDataModel posts;
// Selection
private Post selected;
#Override
protected void initSpecific() {
posts = new LazyPostDataModel(postService);
}
// Actions
public void approve() {
if (selected == null) return;
Post post = postService.find(selected.getId());
post.setModerationApproved(Boolean.TRUE);
postService.edit(post);
}
public void reject() {
if (selected == null) return;
Post post = postService.find(selected.getId());
post.setModerationApproved(Boolean.FALSE);
postService.edit(post);
}
public LazyPostDataModel getPosts() {
return posts;
}
public void setPosts(LazyPostDataModel posts) {
this.posts = posts;
}
public Post getSelected() {
return selected;
}
public void setSelected(Post selected) {
this.selected = selected;
}
}
this is because you have
filterBy="#{post.moderationApproved}"
and
<p:selectOneButton onchange="PF('ModerationPostTable').filter()">
both of these will call the filter once and cause the load method to be called twice.
Use one of them only.

pagination with lazy loading in primefaces donesn't work properly

I am getting a problem with lazy loading in dataTable but couldn't to know where the problem is,
here is my xhtml page code:
<f:view xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Application</title>
</h:head>
<h:body>
<h:form>
<h:panelGrid columns="2">
<h:outputLabel value="Element per page"/>
<p:selectOneMenu value="#{applicationManagementListBean.pageSize}">
<f:selectItem itemLabel="5" itemValue="5"/>
<f:selectItem itemLabel="10" itemValue="10"/>
<f:selectItem itemLabel="30" itemValue="30"/>
<f:selectItem itemLabel="50" itemValue="50"/>
<p:ajax event="change" update="applicationDataList"/>
</p:selectOneMenu>
</h:panelGrid>
<p:commandButton value="New application"
action="inscription.xhtml?faces-redirect=true" ajax="false" />
<p:dataTable id="applicationDataList" value="#{applicationManagementListBean.applications}"
var="app" paginator="true"
rows="#{applicationManagementListBean.pageSize}" lazy="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}">
<p:column headerText="Code">
<h:outputText value="#{app.code}" />
</p:column>
<p:column headerText="Name">
<h:outputText value="#{app.name}" />
</p:column>
<p:column headerText="Abreviate name">
<h:outputText value="#{app.abrevName}" />
</p:column>
<p:column headerText="Status">
<h:outputText value="#{app.status.description}" />
</p:column>
</p:dataTable>
</h:form>
</h:body>
</f:view>
and the bean code:
#ManagedBean
#ViewScoped
public class ApplicationManagementListBean implements Serializable {
private static final long serialVersionUID = 1L;
#ManagedProperty(value = "#{applicationManagementService}")
public ApplicationManagementRemote applicationManagementService;
private Integer pageSize = 3;
private DataProxyLazyDataModel data;
public void setApplicationManagementService(
ApplicationManagementRemote applicationManagementService) {
this.applicationManagementService = applicationManagementService;
}
public LazyDataModel<Object> getApplications() {
data = new DataProxyLazyDataModel(applicationManagementService);
data.setPageSize(pageSize);
return data;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public DataProxyLazyDataModel getData() {
return data;
}
public void setData(DataProxyLazyDataModel data) {
this.data = data;
}
}
when I click on the next page button nothing happen
please help
thanks a lot
best regards, Rachid
primegaces 3.4.2, liferay portal 6.1, eclipse
try adding setRowCount() to your lazyDataModel.
for example:
lazyDataModel.setRowCount(rows);
where rows represents total records in your Database to display in DataTable.
In your case code is:
data.setRowCount(rows);

Resources