Reputation: 345
I am upgrading primefaces 3 to 8. Already working datatable filters in 3 started not to work properly in 8. While entering an existing value to filter returning no data, "load" method seems is not triggered. However, sorting column is triggering load method.
I compared with working example in primefaces showcase for lazy example of datatable, its already the same. Checked logs, inspected page for any error, but can't find anything.
Why it is not working? How can I debug it?
<ui:define name="content">
<h:form id="logsform">
<p:panel>
<p:dataTable id="tbl" var="log"
value="#{logBean.operationLogDataModel}" lazy="true" rows="10"
paginator="true" emptyMessage="#{messages['common.datatable.emptymessage']}">
<p:column sortBy="#{log.custNo}" filterBy="#{log.custNo}">
<f:facet name="header">
<h:outputText value="CustNo" />
</f:facet>
<h:outputText value="#{log.custNo}" />
</p:column>
</p:dataTable>
</p:panel>
</h:form>
My logBean is likely:
@ViewScoped
@FacesConfig(version = FacesConfig.Version.JSF_2_3)
@Named("logBean")
public class LogBean implements Serializable {
@Inject
@ManagedProperty("#{logBo}")
private LogBo logBo;
OperationLogDataModel operationLogDataModel;
AuthUser authUser = (AuthUser) SecurityContextHolder.getContext().getAuthentication();
public LogBean() {
}
@PostConstruct
public void initModel() {
operationLogDataModel = new OperationLogDataModel(logBo, authUser);
documentLogList = new ArrayList<DocumentLog>();
}
.
.
}
My lazyDataModel is as follows:
public class OperationLogDataModel extends LazyDataModel<OperationLogs> {
private static final Logger LOG = Logger.getLogger(OperationLogDataModel.class);
private LogBo logBo;
private String currentSortField;
private SortOrder currentSortOrder;
private Map<String, FilterMeta> currentFilters;
AuthUser authUser;
private Date startDate;
private Date finishDate;
public OperationLogDataModel() {
}
public OperationLogDataModel(LogBo logBo, AuthUser authUser) {
this.authUser = authUser;
this.logBo = logBo;
super.setPageSize(Configurations.PAGE_SIZE);
}
public OperationLogDataModel(LogBo logBo, AuthUser authUser, Date startDate, Date finishDate) {
this.logBo = logBo;
this.authUser = authUser;
super.setPageSize(Configurations.PAGE_SIZE);
this.startDate = startDate;
this.finishDate = finishDate;
}
@Override
public List<OperationLogs> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, FilterMeta> filters) {
currentSortField = sortField;
currentSortOrder = sortOrder;
currentFilters = filters;
if (sortField == null) {
sortField = "createTime";
sortOrder = SortOrder.DESCENDING;
}
Criterion sqlRestriction = Restrictions.sqlRestriction("1=1");
if (startDate != null)
sqlRestriction = Restrictions.and(sqlRestriction, Restrictions.ge("createTime", startDate));
if (finishDate != null)
sqlRestriction = Restrictions.and(sqlRestriction, Restrictions.le("createTime", finishDate));
List<OperationLogs> logs = new ArrayList<OperationLogs>();
try {
if (authUser.getAuthorityName().equals(Role.ROLE_ORDINARY.getName()))
sqlRestriction = Restrictions.and(sqlRestriction, Restrictions.eq("username", authUser.getName()));
super.setRowCount(logBo.countLogs(-1, -1, null, sortOrder.name(), filters, null, sqlRestriction).intValue());
System.out.println("load called!");
logs = logBo.listLogs(first, pageSize, sortField, sortOrder.name(), filters, null, sqlRestriction);
} catch (Exception e) {
LOG.error(e, e);
}
return logs;
}
@Override
public String getRowKey(OperationLogs logs) {
return logs.getId() + "";
}
@Override
public OperationLogs getRowData(String rowKey) {
try {
return logBo.getLogById(Long.parseLong(rowKey));
} catch (Exception e) {
return null;
}
}
@Override
public void setPageSize(int pageSize) {
super.setPageSize(pageSize);
}
public void onFilter(AjaxBehaviorEvent event) {
}
public String getCurrentSortField() {
return currentSortField;
}
public void setCurrentSortField(String currentSortField) {
this.currentSortField = currentSortField;
}
public SortOrder getCurrentSortOrder() {
return currentSortOrder;
}
public void setCurrentSortOrder(SortOrder currentSortOrder) {
this.currentSortOrder = currentSortOrder;
}
public Map<String, FilterMeta> getCurrentFilters() {
return currentFilters;
}
public void setCurrentFilters(Map<String, FilterMeta> currentFilters) {
this.currentFilters = currentFilters;
}
}
logBo.listLogs in load method above is just calling findEntities method below. But I don't think execution reaches here as load method above is never called when filtering despite being called and working properly in sort. I think so because the printly before logBo.listLogs
@Override
public List<T> findEntities(int first, int pageSize, String sortField,
String sortOrder, Map<String, FilterMeta> filters,
Map<String, String> aliases, Criterion extraCriterion)
throws SecurityException, NoSuchFieldException {
Criteria crit = sessionFactory.getCurrentSession().createCriteria(
getPersistentClass());
crit = prepareCriteria(first, pageSize, sortField, sortOrder, filters,
aliases, extraCriterion, crit);
crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return crit.list();
}
private Criteria prepareCriteria(int first, int pageSize, String sortField,
String sortOrder, Map<String, FilterMeta> filters,
Map<String, String> aliases, Criterion extraCriterion, Criteria crit)
throws NoSuchFieldException {
if (aliases != null && !aliases.isEmpty()) {
Iterator<Entry<String, String>> iterator = aliases.entrySet()
.iterator();
while (iterator.hasNext()) {
Entry<String, String> entry = iterator.next();
crit.createAlias(entry.getKey(), entry.getValue(),
Criteria.LEFT_JOIN);
}
}
if (extraCriterion != null) {
crit.add(extraCriterion);
}
if (sortField != null && !sortField.isEmpty()) {
if (!sortOrder.equalsIgnoreCase("UNSORTED")) {
if (sortOrder.equalsIgnoreCase("ASCENDING")) {
crit = crit.addOrder(Order.asc(sortField));
} else {
crit = crit.addOrder(Order.desc(sortField));
}
}
}
if (filters != null && !filters.isEmpty()) {
Iterator<Entry<String, FilterMeta>> iterator = filters.entrySet()
.iterator();
while (iterator.hasNext()) {
Entry<String, FilterMeta> entry = iterator.next();
Class<?> type = getPersistentClass().getDeclaredField(
entry.getKey()).getType();
try {
if (type.isEnum() || Number.class.isAssignableFrom(type)
|| Double.class.isAssignableFrom(type)) {
crit = crit.add(Restrictions.eq(entry.getKey(), type
.getDeclaredMethod("valueOf", String.class)
.invoke(null, entry.getValue())));
} else {
crit = crit.add(Restrictions.like(entry.getKey(),
String.valueOf(entry.getValue().getFilterValue()), MatchMode.START));
}
} catch (Exception ex) {
}
}
}
if (first != -1) {
crit = crit.setFirstResult(first);
}
if (pageSize != -1) {
crit = crit.setMaxResults(pageSize);
}
return crit;
}
PS Update: Seems I am mistaken, load is called during filter. Possibly I need to check my custom generic filtering code.
Upvotes: 0
Views: 1279
Reputation: 345
I found out that once I enter some value to column A filterBy field, the other columns filterBy fields which I left intentionally empty enters the custom query as:
CriteriaImpl(com.xxx.model.OperationLogs:this[][1=1, custNo like 11111%, refNo like null%, username like null%])
So adding a control while query generation:
if(entry.getValue().getFilterValue() == null) {
continue;
}
just after:
if (filters != null && !filters.isEmpty()) {
Iterator<Entry<String, FilterMeta>> iterator = filters.entrySet()
.iterator();
while (iterator.hasNext()) {
solved the problem.
I was doing a total upgrade including Primefaces, JSF, Spring, Hibernate, etc I think I have missed something in hibernate upgrade, as it was working in previous version successfully.
Upvotes: 1