0
votes

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.

1
Have you checked the Migration guide? You're getting the empty message, so the load seems called. How do you do the filter part? Since PF > 5 filter value is an Object and not a String - WoAiNii
Yes, I was doing the upgrade according to migration guide. But I may have miss things. Added the load method signature. By the way, I am sure "load" is not called on filterBy whereas it is called when sorting by checking logs. - bahadir_g
Have you tried with a plain page, without composition and any other component (as a minimal reproducible example)? Can you post your logBean definition and all your lazy bean? - WoAiNii
Added the logbean and lazyModel. I will try the plain version as soon as possible and inform you. Thank you - bahadir_g
PS Update: Seems I am mistaken, load is called during filter. Possibly, I need to check my custom generic filtering code. - bahadir_g

1 Answers

1
votes

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.