Search code examples
jsfjsf-2

h:dataTable displays the correct number but blank rows


My JSF application is behaving strangely, and I ask colleagues to help me identify a solution.

The application fetches data from the database through Facade+DAO classes, and through debug and println I can state that the object collection is correct (in the example below, the collection contains the 5 objects and their attributes), however, when passing this collection to the Primefaces page, dataTable does not display the attributes, it becomes clear that the the amount of rows is correct but the attributes are not displayed as shown in the figure.

I researched other posts, but the errors described do not resemble mine:

after filtering Empty rows blank rows displayed while paging in the datatable using Primefaces

primefaces datatable is showing blank rows. Showing the same number of rows as the records in backed list

Since the managed bean is reposting the collection correctly, I figured the issue should be on display (ie on the JSF page), and to try to find where the fault could be, I created a page without using Primefaces or Facelets, just pure JSF components, but the failure persisted. The basic code looks like this:

Here are the code snippets:

  • simple page

    <html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:h="http://java.sun.com/jsf/html">
    
    <h:head>
        <link href="scripts/teste.css" rel="stylesheet" type="text/css" media="all" />
    </h:head>
    <h:body>
        <h:form>    
            <h:dataTable value="#{coletaMB.coletas}" var="coleta"
                styleClass="order-table"
                headerClass="order-table-header"
                rowClasses="order-table-odd-row,order-table-even-row">
               <h:column>
                    <f:facet name="header">Nr. Setor</f:facet>
                        <h:outputText value="#{coleta.setor.numero}"/>
                               ---- #{coleta.setor.numero} ----
               </h:column>
           </h:dataTable>       
       </h:form>
    

With this simple code, the page looks like this:

simple JSF page

  • managed bean

    @ManagedBean(name="coletaMB")
    @SessionScoped
    public class ColetaMB{
        @ManagedProperty(name="coleta", value="#{coleta}")
        private Coleta coleta;
        @ManagedProperty(name="coletaFacade", value="#{coletaFacade}")
        private ColetaFacade coletaFacade;
        private List<Coleta> coletas;
    
    
        public List<Coleta> getColetas(){
            if(coletas == null){
                coletas = getListColetas();
            }
            return coletas;
        }
    
        private List<Coleta> getListColetas(){
            coletas = new ArrayList<Coleta>();
            try {
                coletas =  coletaFacade.getColetas();
                return coletas;
            } catch (DAOException e) {
                (...)
            }
        }
        (...)
    }
    
  • Coleta.java

    public class Coleta {
        private int ano;
        private Setor setor;
        private int mes;
        private int semana;
        private int numeroEntrevista;
    
        (*)getters and setter
    }
    
  • Setor.java

    public class Setor {
        private Agencia agencia;
        private String numero;
        private String upa;
    
        (*)getters and setters
    }
    
  • Agencia.java

    public class Agencia {
        private int idAgencia;
        private String nome;
    
        (*)getters and setters
    }
    
  • Facade

    public List<Coleta> getColetas() throws DAOException {
        return dao.getColetas();
    }
    
  • DAO

    @Value("#{queries.sql01}")
    private String sql01;
    
    public List<Coleta> getColetas() throws DAOException {
        try{
            RowMapper<Coleta> mapper = getRowMapper();
            return getJdbcTemplate().query(sql01, mapper);
        } catch (DataAccessException de) {
            de.printStackTrace();
            throw new DAOException(de.getMessage());
        }
    }
    
    private RowMapper<Coleta> getRowMapper() {
        return new RowMapper<Coleta>() {
            public Coleta mapRow(ResultSet rs, int rowNum) throws SQLException {
                Agencia ag = new Agencia();
                ag.setIdAgencia(rs.getInt(1));
                ag.setNome(rs.getString(2));
    
                Setor s = new Setor();
                s.setAgencia(ag);
                s.setUpa(rs.getString(3));
                s.setNumero(rs.getString(4));
    
                Coleta c = new Coleta();
                c.setSetor(s);
                c.setAno(rs.getInt(5));
                c.setMes(rs.getInt(6));
                c.setSemana(rs.getInt(7));
                c.setNumeroEntrevista(rs.getInt(8));
    
                return c;
            }
        };
    }
    

In getListColetas, I inserted a println to verify the collection and it is complete, that is, each object 'coleta' has the object 'setor' and each 'setor' has the object 'agencia'. But, following the suggestion of using 'empty' on the JSF page,

<h:outputText value="#{empty coleta} - #{empty coleta.setor} - #{empty coleta.setor.numero}"/>

the return was false - true - true, and I don't know why.

My complete application is using the following libraries and dependencies (Spring is only used for DI and DAO classes):

build path


Solution

  • Resolved: in dataTable tag, I changed the attribute var="coleta" to var="c", like this:

    <h:dataTable value="#{coletaMB.coletas}" var="c"
            styleClass="order-table"
            headerClass="order-table-header"
            rowClasses="order-table-odd-row,order-table-even-row">
           <h:column>
                <f:facet name="header">Nr. Setor</f:facet>
                    <h:outputText value="#{c.setor.numero}"/>
                           ---- #{c.setor.numero} ----
           </h:column>
    </h:dataTable>   
    

    I imagine JSF was conflicting with the @ManagedProperty 'coleta' in ColetaMB, although I understand that the var attribute is specific to varying collection objects delivered to dataTable.