【问题标题】:h:dataTable displays the correct number but blank rowsh:dataTable 显示正确的数字但空白行
【发布时间】:2020-01-23 20:39:43
【问题描述】:

我的 JSF 应用程序行为异常,我请同事帮我确定解决方案。

应用程序通过 Facade+DAO 类从数据库中获取数据,通过 debug 和 println 我可以声明对象集合是正确的(在下面的示例中,集合包含 5 个对象及其属性),但是,当把这个集合传到Primefaces页面,dataTable不显示属性,很明显行数正确但是属性不显示如图。

我研究了其他帖子,但描述的错误与我的不同:

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

由于托管 bean 正确地重新发布集合,我认为应该显示问题(即在 JSF 页面上),并且为了尝试找出可能的故障所在,我创建了一个页面而不使用 Primefaces 或 Facelets,只是纯 JSF 组件,但故障仍然存在。基本代码如下所示:

这里是sn-ps的代码:

  • 简单的页面

    <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>
    

使用这个简单的代码,页面看起来像这样:

  • 托管豆

    @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
    }
    
  • 立面

    public List<Coleta> getColetas() throws DAOException {
        return dao.getColetas();
    }
    
  • @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;
            }
        };
    }
    

getListColetas 中,我插入了一个 println 来验证集合是否完整,即每个对象“coleta”都有对象“setor”,每个“setor”都有对象“agencia”。但是,按照在 JSF 页面上使用“空”的建议,

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

返回的是false - true - true,我不知道为什么。

我的完整应用程序正在使用以下库和依赖项(Spring 仅用于 DI 和 DAO 类):

【问题讨论】:

  • 由于使用纯 JSF dataTable 问题仍然存在,因此它似乎与 primefaces 无关。您确定 #{coleta.setor} 的 setor 属性已初始化且非 null 吗?
  • 调试的时候,集合的值不为空?也许您的 getter 需要检查集合是否为空并重新计算其值!还要确保您的 ManagedBean 具有 @ViewScoped 注释!结帐stackoverflow.com/questions/7031885/… 并检查此getter 行为stackoverflow.com/questions/2090033/… 它也发生在数据表中stackoverflow.com/questions/22662276/…
  • @Selaron,感谢您的回归。老实说,我不知道“空运算符”,您的观察帮助我更好地理解。使用您的 outputText 建议,返回是“假 - 真 - 真”。但是,在集合列表中创建一个 for (在返回页面之前)会打印出: Coleta [setor=520010005000015, ano=2019, mes=8, semana=3, numeroEntrevista=1] >> 5 lines 也就是说,setor既不是 null 也不是空的,并且有一个 'numero'。
  • BugsForBreakfast,感谢您的评论。集合值不为空(我做了一个 for 并列出了元素)并且托管 bean 具有 @SessionScoped 注释
  • @RogerioArantes 我明白了,你知道它也可能是什么,也许你的数据 FetchType 是“LAZY”,你能检查一下吗?因为是这种情况,如果你想把一个对象的数据放在另一个对象内部,那么像这样的语句 只能使用主键或外键并且您使用的是 LAZY 而不是 EAGER,您必须使用模式 DTO(数据访问对象),在此对象中,您将拥有要在数据表上显示的所有对象的所有属性,请检查您是否使用 LAZY,检查它在你的模型吸气剂上

标签: jsf jsf-2


【解决方案1】:

已解决:在dataTable标签中,我将属性var="coleta"改为var="c",如下:

<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>   

我想 JSF 与 ColetaMB 中的 @ManagedProperty 'coleta' 冲突,尽管我知道 var 属性特定于传递到 dataTable 的不同集合对象。

【讨论】:

    猜你喜欢
    • 2015-01-06
    • 1970-01-01
    • 2017-04-19
    • 2018-06-16
    • 2013-08-14
    • 1970-01-01
    • 1970-01-01
    • 2014-06-27
    • 1970-01-01
    相关资源
    最近更新 更多