PrimeFaces 12 dataTable编辑行无法更新对象,旧值传入Bean求助
PrimeFaces 12 DataTable编辑行后后端接收旧值的解决办法
问题原因
核心问题出在RiderView的getAllRiders()方法上——每次调用这个方法都会从EJB重新查询数据库获取骑手列表。当点击“Save Row”触发ajax请求时,JSF会重新调用getAllRiders()渲染组件,导致当前View中正在编辑的Rider对象被新查询的旧对象覆盖,最终onRowEdit方法拿到的是重新加载的旧数据。哪怕把实体复制到POJO,只要getter方法每次都重新查询,新的POJO实例也会被覆盖,问题依然存在。
解决方案
1. 缓存骑手列表到Bean字段
在RiderView中添加私有字段缓存列表,通过@PostConstruct注解在Bean初始化时一次性加载数据,后续getAllRiders()直接返回缓存的列表,不再每次查询数据库:
修改后的Bean代码:
@ViewScoped @Named("riderView") public class RiderView implements Serializable { private final RiderEjb riderEjb; private final SecurityOfficer securityOfficer; private List<Rider> allRiders; // 新增缓存字段 public RiderView() { this(null, null); } @Inject public RiderView(RiderEjb riderEjb, SecurityOfficer securityOfficer) { this.riderEjb = riderEjb; this.securityOfficer = securityOfficer; } @PostConstruct public void init() { // 初始化时加载一次数据 allRiders = riderEjb.findAll(securityOfficer.getTeam()); } public List<Rider> getAllRiders() { // 返回缓存的列表,避免重复查询 return allRiders; } public void onRowEdit(RowEditEvent<Rider> event) { Rider editedRider = event.getObject(); riderEjb.addOrUpdate(editedRider); // 可选:如果需要刷新列表显示最新数据,更新缓存或重新加载 int index = allRiders.indexOf(editedRider); if (index != -1) { allRiders.set(index, editedRider); } FacesMessage msg = new FacesMessage("骑手已编辑", editedRider.getName()); FacesContext.getCurrentInstance().addMessage(null, msg); } public void onRowCancel(RowEditEvent<Rider> event) { FacesMessage msg = new FacesMessage("编辑已取消", event.getObject().getName()); FacesContext.getCurrentInstance().addMessage(null, msg); } }
2. 验证Lombok setter有效性
确保Rider实体类的@Setter注解正确生成了setter方法。可以手动编写setter方法测试,或者查看编译后的class文件确认setter存在——如果Lombok配置不当,可能导致属性无法被正确赋值。
3. 确认DataTable配置正确性
检查你的dataTable配置:
editable="true"已正确设置p:cellEditor的input部分绑定的是rider的对应属性(你的代码中这部分是正确的)
内容的提问来源于stack exchange,提问作者Jaap D
相关产品推荐
相关产品推荐

