EntityManager保存数据后如何正确刷新p:dataView组件?
解决PrimeFaces p:dataView保存后刷新显示旧数据的问题
1. 保存后重新加载数据源
问题核心往往是Bean中绑定到p:dataView的集合还是旧的内存数据,没有从数据库重新获取。在保存方法末尾必须重新查询并覆盖该集合:
public void saveBillingAddress() { // 执行保存逻辑 em.merge(selectedBillingAddress); em.flush(); // 强制将变更写入数据库(可选,视事务配置而定) // 重新查询最新的地址列表,覆盖原有集合 billingAddresses = em.createQuery("SELECT a FROM BillingAddress a", BillingAddress.class).getResultList(); }
不要依赖@PostLoad事件,它仅在实体被加载时触发,无法自动更新Bean中已存在的集合引用。
2. 用组件属性管理AJAX流程,避免手动update
放弃在Bean中调用PrimeFaces.current().ajax().update(),改用保存按钮的execute和update属性让PrimeFaces管控AJAX生命周期,确保保存逻辑完成后再刷新组件:
<p:commandButton value="保存" action="#{billingAddressBean.saveBillingAddress}" execute="@form" update=":dvBillingAddresses :editBillingAddressDialog" oncomplete="PF('editBillingAddressDialog').hide()"/>
execute="@form"确保表单数据完整提交update指定要刷新的数据视图和对话框,PrimeFaces会在服务器端保存完成后自动执行刷新oncomplete在AJAX请求彻底完成后关闭对话框,避免提前操作
3. 清除EclipseLink缓存,确保获取最新数据
EclipseLink的一级缓存(EntityManager级)会缓存已加载的实体,导致重新查询时仍拿到旧数据。保存后可针对性刷新实体或清除缓存:
public void saveBillingAddress() { em.merge(selectedBillingAddress); em.flush(); // 刷新当前实体,更新缓存中的状态 em.refresh(selectedBillingAddress); // 或清除该类实体的缓存(适用于多实例引用的场景) em.getEntityManagerFactory().getCache().evict(BillingAddress.class, selectedBillingAddress.getId()); // 重新加载地址列表 billingAddresses = em.createQuery("SELECT a FROM BillingAddress a", BillingAddress.class).getResultList(); }
4. 手动update时确保事务提交后执行
如果必须手动调用update,需保证在事务提交后触发。可通过AJAX回调参数配合前端oncomplete实现:
public void saveBillingAddress() { // 保存逻辑 em.merge(selectedBillingAddress); // 传递保存成功的回调参数 PrimeFaces.current().ajax().addCallbackParam("saveSuccess", true); }
前端按钮配置:
<p:commandButton value="保存" action="#{billingAddressBean.saveBillingAddress}" execute="@form" oncomplete="if (args.saveSuccess) { PF('editBillingAddressDialog').hide(); PrimeFaces.current().ajax().update(':dvBillingAddresses'); }"/>
内容的提问来源于stack exchange,提问作者SergioBrito
相关产品推荐
相关产品推荐

