0

I have a problem similar to the ones described here:

primefaces datatable not displaying anything

PrimeFaces DataTable "No records found" when there are records

my PrimeFaces datatable does not show any results, altough there are records in the database. Moreover: it seems that NO JAVA method is called when I request the page from the browser - at least the init() method of the backing bean seems not to be called at all

Where can the problem be? I would appreciate any help!

Thank you!

My template:

<!DOCTYPE html>
<html 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:c="http://java.sun.com/jsp/jstl/core">
<h:head>
    <meta charset="UTF-8"/> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
    <title>Bibliothek - Customers </title>  
</h:head>
<h:body>
    <h:form id="customersform">
        <p:growl id="growl" life="2000" />

        <p:panel header="All customers in the application" />

        <p:dataTable id="customersTable" var="customer"
            value="#{kundenBean.dataModel}" paginator="true" rows="10"
            paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
            resizableColumns="true" rowsPerPageTemplate="5,10,15"
            selection="#{kundenBean.selektierterKunde}" selectionMode="single"
            rowKey="#{customer.id}" lazy="true">

            <p:column headerText="Customer's Name" style="width:332px;text-align:center"
                sortBy="#{customer.vorname}" filterBy="#{customer.vorname}">
                <h:outputText value="#{customer.vorname}" />
            </p:column>
            <p:column headerText="Customer's Address" sortBy="#{customer.adresse}"
                filterBy="#{customer.adresse}">
                <h:outputText value="#{customer.adresse}" />
            </p:column>
        </p:dataTable>

    </h:form>
</h:body>
</html>

The Backing Bean:

@Named
@ViewScoped
public class KundenBean {

    private Logger logger = Logger.getLogger(KundenBean.class.getName());
    public static final String SELECTED_CUSTOMER = "selectedCustomer";

    @Inject
    private KundeDBService kundenDBService;

    private LazyKundeDataModel dataModel;

    private Kunde selektierterKunde;
    private int selectedCustId;


    @PostConstruct
    private void init() {
        this.dataModel = new LazyKundeDataModel(kundenDBService);
    }


    public LazyKundeDataModel getDataModel() {
        return dataModel;
    }

    public void setDataModel(LazyKundeDataModel dataModel) {
        this.dataModel = dataModel;
    }

    public Kunde getSelektierterKunde() {
        return selektierterKunde;
    }

    public int getSelectedCustId() {
        return selectedCustId;
    }

    public void setSelektierterKunde(Kunde selektierterKunde) {
        this.selektierterKunde = selektierterKunde;
    }

    public void onRowSelect(SelectEvent event) {
        selectedCustId = ((Kunde) event.getObject()).getId();
    }

    public void onRowDblClick(final SelectEvent event) {
        selectedCustId = ((Kunde) event.getObject()).getId();

        try {
            ExternalContext extCtx = FacesContext.getCurrentInstance()
                    .getExternalContext();

            extCtx.getFlash().put(SELECTED_CUSTOMER,((Kunde) event.getObject()));

            FacesContext.getCurrentInstance().getExternalContext().redirect("rents.xhtml?custId=" +selectedCustId);
        } catch (IOException e) {
            e.printStackTrace();
            logger.error(e.getMessage(), e);
        }

    }
}

The Data Model:

public class LazyKundeDataModel extends LazyDataModel<Kunde> {

    private static final long serialVersionUID = 1L;

    private KundeDBService kundeDBService;

    public LazyKundeDataModel(KundeDBService kundeDBService) {
        this.kundeDBService = kundeDBService;
    }

    @Override
    public Kunde getRowData(String rowKey) {
        return kundeDBService.getKundeById(Integer.valueOf(rowKey));
    }

    @Override
    public Object getRowKey(Kunde kunde) {
        return kunde.getId();
    }

    @Override
    public List<Kunde> load(int first, int pageSize, String sortField, SortOrder sortOrder,
            Map<String, Object> filters) {


        List result = this.kundeDBService.load(first, pageSize, sortField, sortOrder, filters);

        // rowCount
        this.setRowCount(result.size());
        this.setPageSize(pageSize);

        return result;
    }
}

The DB Service:

@Stateless
public class KundeDBService {

    @PersistenceContext
    private EntityManager em;

    public static final String JOINING_OR = " OR ";
    public static final String JOINING_AND = " AND ";
    public static final String CONDITION_WHERE = " WHERE ";

    private static Logger logger = Logger.getLogger(KundeDBService.class.getName());

    public List<? extends Kunde> load(int first, int pageSize, String sortField, SortOrder sortOrder,
            Map<String, Object> filters) {

        List<? extends Kunde> result = new ArrayList<Kunde>();

        String selectQUERY = " select k from Kunde k ";

        if (filters.size() > 0) {
            selectQUERY += addFiltersToQuery(filters);
        }

        if (sortField != null) {
            selectQUERY += " order by k." + sortField;

            if (sortOrder != null) {
                selectQUERY += " " + (sortOrder);
            }
        }else { // sortField == null, default sort by customer's name

            selectQUERY += " order by k.vorname asc";

        }

        Query emQuery = em.createQuery(selectQUERY);

        emQuery.setFirstResult(first);
        emQuery.setMaxResults(pageSize);

        result = (List<Kunde>) emQuery.getResultList();
        return result;
    }

    private String addFiltersToQuery(Map<String, Object> filters) {

        if (filters.size() == 0)
            return StringUtils.EMPTY;

        StringBuilder whereCondition = new StringBuilder(CONDITION_WHERE);

        int pseudoCounter = 0;
        for (Entry<String, Object> entry : filters.entrySet()) {
            whereCondition.append("k." + entry.getKey() + " LIKE :" + "x" + (++pseudoCounter));
            whereCondition.append(JOINING_AND);
        }

        if (whereCondition.length() > CONDITION_WHERE.length()) {
            whereCondition.delete(whereCondition.length() - JOINING_AND.length(), whereCondition.length());
        }

        return whereCondition.toString();
    }

    public Kunde getKundeById(int id) {

        return em.find(Kunde.class, Integer.valueOf(id));

    }
}
Alex Mi
  • 1,409
  • 2
  • 21
  • 35
  • If no method is called you can exclude all db stuff and remove it from the question. Narrow the problem down... – Kukeltje Mar 31 '18 at 12:39
  • @Kukeltje I see that even the init() method of the backing bean is not called in the debugger, altough it is marked with the annotation PostConstruct – Alex Mi Mar 31 '18 at 16:00
  • Then narrow down the problem even more. You can exclude an additional class and really reformulate your question. – Kukeltje Mar 31 '18 at 16:33
  • According to the specs, the @PostConstruct annotated init() method may be private but did you try changing it to public – Kukeltje Mar 31 '18 at 21:02
  • @Kukeltje I just made init() public, but there is no difference. – Alex Mi Apr 01 '18 at 06:09

1 Answers1

0

I solved the problem by replacing the annotation @Named by the annotation javax.faces.bean.ManagedBean on the KundenBean class. I am not sure what exactly the problem was, but I suppose that it has something to do with the problem outlined here

JSF View Scoped Bean Reconstructed Multiple Times

So, now the changed and working KundenBean class looks like this:

@ManagedBean (name = "kundenBean")
@ViewScoped
public class KundenBean {

//rest of the lines unchanged
Alex Mi
  • 1,409
  • 2
  • 21
  • 35
  • If you in this step **_DID NOT_** change the `@ViewScoped` annotation, your problem was #3 in https://stackoverflow.com/questions/5541813/viewscoped-calls-postconstruct-on-every-postback-request. Your change and this answer is a bad one considering the deprecation of ManagedBean – Kukeltje Apr 15 '18 at 13:44
  • @Kukeltje thank you for your contribution! I suppose you are right. Considering the deprecation of ManagedBean: I took the official PrimeFaces showcase for Datatable + Paginator: There, the backing bean is annotated the same way (@ManagedBean + @ViewScoped) – Alex Mi Apr 16 '18 at 06:36
  • Yes, there has been discussion about this to change it to @Named https://forum.primefaces.org/viewtopic.php?t=43480 and there is/was even an issue in github, but they won't change it for now (will for PF 7.0 iirc) – Kukeltje Apr 16 '18 at 06:49
  • Can you please check since I'm inclined to downvote the answer since other people should, because of the deprecation, not switch `@Named` annotations to `@ManagedBean` – Kukeltje Apr 16 '18 at 07:15
  • I will check it and let you know – Alex Mi Apr 16 '18 at 09:25