0

I'm trying to render a list of products in a .xhtml page, from my database in Postgres: i'm using the JSF tag h:dataTable. Unfortunately, when I display the page, I get the message "The catalogue is empty", so it seems like it can't get the values from the database. This is the page i'm talking about:

<f:metadata>
    <f:viewParam id="prodotto_id" name="id" value="#{prodotto.id}"
        required="true"
        requiredMessage="Invalid page access. Please use a link from within the system."/>
</f:metadata>
<h:message for="prodotto_id" />

<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Catalogo</title>
</h:head>
<h:body>
    <h2>Catalogo Prodotti</h2>
    <h:form>
        <h:outputText value="The catalogue is empty."
            rendered="#{empty prodottoController.prodotti}" />
        <h:dataTable value="#{prodottoController.prodotti}" var="prodotto"
            rendered="#{not empty prodottoController.prodotti}">
            <h:column>
                <f:facet name="header">Nome</f:facet>
                <h:commandLink action="#{prodottoController.findProdotto}"
                    value="#{prodotto.nome}" style="color: orange">
                    <f:param name="id" value="#{prodotto.id}" ></f:param>
                </h:commandLink>
            </h:column>
            <h:column>
                <f:facet name="header">Prezzo per unità</f:facet>
                <h:outputText value="#{prodotto.prezzo}" />
            </h:column>
            <h:column>
                <f:facet name="header">Codice</f:facet>
                <h:outputText value="#{prodotto.codice}" />
            </h:column>
            <h:column>
                <f:facet name="header">Quantità in magazzino</f:facet>
                <h:outputText value="#{prodotto.quantita}" />
            </h:column>
            <h:column>
                <f:facet name="header"></f:facet>
                <h:commandButton action="/newRigaOrdine.xhtml?faces-redirect=true"
                    value="Aggiungi all'ordine"
                    rendered="#{not empty loginCliente.clienteLoggato.email 
                                and empty loginAdmin.admin.email}">
                </h:commandButton>
            </h:column>
            <h:column>
                <f:facet name="header"></f:facet>
                <h:commandButton action="#{prodottoController.deleteProdotto}"
                    value="Elimina Prodotto"
                    rendered="#{not empty loginAdmin.admin.email and empty loginCliente.clienteLoggato.email}">
                    <f:param name="id" value="#{prodotto.id}" />
                </h:commandButton>
            </h:column>
        </h:dataTable>
        <h:outputLink value="formCreaProdotto.xhtml?faces-    redirect=true"
            rendered="#{not empty loginAdmin.admin.email and empty    loginCliente.clienteLoggato.email}">Aggiungi un prodotto al catalogo</h:outputLink>
    </h:form>
</h:body>
</html>

This is the prodottoController managed bean:

 @ManagedBean (name="prodottoController")
@ViewScoped
public class ProdottoController implements Serializable {


    private static final long serialVersionUID = 1L;


    private Long id;

    private String nome;
    private Float prezzo;
    private String descrizione;
    private String codice;
    private int quantita;

    private String errore;

    private Prodotto prodotto;
    private List<Prodotto> prodotti;

    @EJB (beanName="pFacade")
    private ProdottoFacade pFacade;



    public String creaProdotto() {
        try {
            this.prodotto = pFacade.creaProdotto(nome, codice, descrizione, prezzo, quantita);
            return "newProdotto"; 
            }
        catch (Exception e) {
            errore="Prodotto già esistente sul database. Per favore inserisci un prodotto con codice differente";
            return errore; 
        }
    }

    public String listProdotti() {
        this.prodotti = pFacade.getCatalogoProdotti();
        return "showProdotti"; 
    }

    public String findProdotto() {
        this.prodotto = pFacade.getProdottoByID(id);
        return "showProdotto";
    }

    public String deleteProdotto() {   
        pFacade.deleteProdottoById(id);
        return "showProdotti";
    } //getters and setters

And this is the facade method getCatalogoProdotti() :

public List<Prodotto> getCatalogoProdotti() {

    try {
        TypedQuery<Prodotto> q = em.createQuery("SELECT p FROM Prodotto p", Prodotto.class);
        return q.getResultList();

    } 
    catch (Exception e) {
        String q = "la lista è vuota";
        System.out.println(q);
        return null;
        }
    }

So, what am I doing wrong?? After hours and hours of studying and searching I really don't know what to do...

Enduavon
  • 39
  • 11
  • Have you ensured that the products' list is well populated in `getCatalogoProdotti()` and that there is no exception or something printed in the console ? – Omar Jun 04 '15 at 11:59
  • As I write below in another comment, everything worked like a charm when I was using ui:repeat and the html tag table in the xhtml page. I only changed all of this with the h:dataTable, and I changed the scope of the bean from Request to View, and now it's not working. In the Eclipse console, I got the message "la lista è vuota", which is the String q I defined in the catch(Exception e) in the facade method....but I don't know which is the exception I got :/ – Enduavon Jun 04 '15 at 12:27
  • Why not keeping the `@RequestScoped` so ? – Omar Jun 04 '15 at 12:30
  • Because it's the perfect annotation scope to use when working with tables, as mentioned here http://stackoverflow.com/questions/8367147/use-of-viewscoped-in-jsf-2-0 (anyway I've tried with every annotation scope and it's not working either, so it depends on the xhtml page) – Enduavon Jun 04 '15 at 14:15

1 Answers1

0

I've found the solution guys! Hope this helps for someone that had my same problem.

I added this

    @PostConstruct
public void init() {
    prodotti = pFacade.getCatalogoProdotti();
} 

in the prodottoController bean, and now it shows all the products on the database!! That PostConstruct must be used everytime we use a ViewScoped bean, as I've read across the internet. Uh, and also the entity class "Prodotto" has to implement Serializable.

Enduavon
  • 39
  • 11