You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PrimeFaces DataTable为空求助:从MySQL加载数据方案

我帮你梳理下导致PrimeFaces DataTable为空的几个关键问题,一个个来解决:

1. EL表达式大小写不匹配(最可能导致空表的原因)

JSF的EL表达式是大小写敏感的,你的代码里有两处明显的不匹配:

  • 托管Bean的名称是productM(@ManagedBean(name="productM")),但页面里用的是#{ProductM.produits}(大写P开头),应该改成#{productM.produits}。
  • 实体类的属性是驼峰命名(比如prixAchat、dateCreation),对应的EL表达式要和getter方法的属性名一致(比如getPrixAchat()对应#{produit.prixAchat}),但你页面里写的是全小写的prixachat、datecreation,这会导致无法读取属性值。

2. Lazy加载配置错误

你的DataTable设置了lazy="true",但并没有实现PrimeFaces的LazyDataModel接口,只是直接绑定了一个普通List。Lazy模式需要自定义模型来处理分页和数据加载逻辑,如果不需要懒加载,直接把lazy="true"去掉即可,这样DataTable会直接加载整个列表数据。

3. 页面XML命名空间拼写错误

页面开头的<html xlmns="http://www.w3.org/1999/xhtml"里的xlmns是拼写错误,正确的是xmlns。这个错误会导致JSF和PrimeFaces的标签无法被正确解析,进而影响DataTable的渲染。

4. 实体类缺少JPA注解(Hibernate无法映射数据库表)

你的Product类没有添加JPA的实体注解,Hibernate根本不知道它对应数据库里的products表,执行from Product查询时要么报错,要么返回空列表。必须给实体类添加注解:

package ma.supmti.jsf.model;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "products") // 明确对应MySQL的products表
public class Product {
    @Id // 标记主键字段
    private Integer id;
    private String name;
    private Integer prixAchat;
    private Integer prixVente;
    private Date dateCreation;

    // 构造函数、getter、setter保持不变
}

5. 托管Bean作用域不合理

你给ProductMB用了@ApplicationScoped,这个作用域是整个应用共享的,初始化一次后就不会再更新数据。对于列表页面来说,@ViewScoped更合适,它会绑定到当前页面的生命周期,每次进入页面都会重新初始化数据:

@ManagedBean(name="productM")
@ViewScoped // 替换@ApplicationScoped
public class ProductMB implements Serializable {
    // 其他代码保持不变
}

6. Hibernate资源管理问题(潜在的查询失败原因)

你的DAOProduct每次查询都创建新的SessionFactory,这不仅效率低,还可能导致资源泄漏。应该把SessionFactory做成静态单例,并且正确管理Session的事务和关闭:

package ma.supmti.jsf.dao;
import org.hibernate.query.Query;
import ma.supmti.jsf.model.Product;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class DAOProduct implements IDAOProduct {
    // 静态单例SessionFactory
    private static SessionFactory sessionFactory;

    static {
        try {
            Configuration config = new Configuration().configure("hibernate.cfg.xml");
            sessionFactory = config.buildSessionFactory();
        } catch (Throwable ex) {
            throw new ExceptionInInitializerError(ex);
        }
    }

    public DAOProduct() { }

    public void addProduct() { }

    public List<Product> selectProduct() {
        Session session = sessionFactory.openSession();
        List<Product> produits = null;
        try {
            session.beginTransaction();
            // 指定泛型类型,避免强制转换
            Query<Product> query = session.createQuery("from Product", Product.class);
            produits = query.list();
            // 控制台打印数据,确认是否查询到结果
            for(Product produit:produits) {
                System.out.println("Produit: " + produit.getName() + ", Prix Achat: " + produit.getPrixAchat());
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            // 异常时回滚事务
            if (session.getTransaction().isActive()) {
                session.getTransaction().rollback();
            }
            e.printStackTrace();
        } finally {
            // 关闭Session,释放资源
            session.close();
        }
        return produits;
    }
}

修改后的页面代码

把上面的问题都修正后,页面代码应该是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui" xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>LISTE DES PRODUITS </title>
<style type="text/css">
body { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px; }
.header { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 18px; }
.bottom { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 9px; text-align: center; vertical-align: middle; color: #8E969D; }
</style>
</h:head>
<body bgcolor="#ffffff">
<!-- 移除lazy="true",修正EL表达式 -->
<p:dataTable value="#{productM.produits}" var="produit" id="produit" paginator="true" rows="10">
<f:facet name="header"> Liste des produits ..................... </f:facet>
<p:column headerText="Id">
<h:outputText value="#{produit.id}" />
</p:column>
<p:column headerText="Name">
<h:outputText value="#{produit.name}" />
</p:column>
<p:column headerText="Prix Achats">
<h:outputText value="#{produit.prixAchat}" />
</p:column>
<p:column headerText="Prix Vente">
<h:outputText value="#{produit.prixVente}" />
</p:column>
<p:column headerText="Date Creation">
<h:outputText value="#{produit.dateCreation}">
    <!-- 添加日期格式化,避免默认的长日期格式 -->
    <f:convertDateTime pattern="yyyy-MM-dd HH:mm:ss" />
</h:outputText>
</p:column>
</p:dataTable>
</body>
</html>

最后验证步骤

  1. 启动应用后,查看控制台是否打印了查询到的产品数据,确认Hibernate是否正确读取了数据库内容。
  2. 打开页面,检查DataTable是否正常显示数据。如果还是为空,检查JSF的日志,看是否有EL表达式错误或者实体映射错误。

内容的提问来源于stack exchange,提问作者Ouafae

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:02:08