如何在CrudPanel中更新条目 解决刷新报错与全量刷新性能问题
问题根因
- 乐观锁异常本质是传入
refreshItem的实例携带的@Version字段值和数据库最新值不匹配:后台调用JPA的save方法后,Hibernate会自动将实体的版本号自增,若传入刷新方法的是更新前的旧实例、或手动构造的未正确填充最新版本号的实例,都会触发版本校验失败。 refreshAll触发RPC节点不存在警告,是因为全量刷新时前端Grid组件仍持有旧节点引用,新旧节点的唯一标识比对不通过导致。
解决步骤
方案1:单条刷新(推荐,性能最优)
- 确认传入
refreshItem方法的参数是instanceRepository.save(instance)返回的持久态对象savedInstance,不要使用调用save之前修改的临时instance对象,JPA的save方法会自动将最新的版本号、更新后的字段回填到返回的对象中。 - 直接调用刷新方法即可:
crudPanel.getDataProvider().refreshItem(savedInstance);
如果仍报版本异常,先从数据库查询最新的完整实例再传入刷新:
MenuItem latestInstance = instanceRepository.findById(savedInstance.getId()).orElseThrow(); crudPanel.getDataProvider().refreshItem(latestInstance);
如果使用的是Vaadin官方Crud组件,也可以直接调用组件提供的刷新方法,自动处理校验逻辑:
crud.refresh(savedInstance);
方案2:全量刷新(适用单条刷新无法满足的场景)
如果业务场景可以接受全量刷新,先清除dataProvider的全部缓存再刷新,即可消除RPC节点不存在的警告:
crudPanel.getDataProvider().clearCache(); crudPanel.getDataProvider().refreshAll();
注意事项
不要手动构造新实例传入refreshItem,手动构造的实例如果没有正确填充数据库中最新的@Version以及所有关联字段的值,都会触发校验失败。
内容的提问来源于stack exchange,提问作者Franco G
相关产品推荐
相关产品推荐

