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