JSF dataTable删除数据库行报错:无法匹配导航案例
我来帮你排查这个点击Delete按钮后出现的导航错误,这种情况大概率是因为你的删除方法返回值和JSF的导航规则不匹配导致的,咱们一步步来解决:
1. 先搞懂报错的原因
无法找到与来自视图ID '/ApagarCategoria.xhtml' 的动作 '#{registarVendedor.deleteCtg(c)}' 匹配的导航案例,结果为 '[entities.Categorias[ categoria=Carro ]]'
这个报错说明:你的deleteCtg方法返回了一个List<Categorias>对象(就是你看到的那个实体列表),而JSF的导航系统会把方法的返回值当作导航结果字符串,去匹配faces-config.xml里的<navigation-case>规则。但你显然没有配置对应这个实体列表的导航规则,所以就报错了。
2. 修改控制器的删除方法
这是最核心的修复步骤,你需要调整RegistoVendedor.java里的deleteCtg方法返回值:
方案一:返回导航字符串(跳转到指定页面)
如果你想删除后跳转到某个页面(比如刷新当前分类列表页面),可以改成返回字符串,还可以加上faces-redirect=true避免视图状态问题:
public String deleteCtg(Categorias ct) { // 调用EJB执行删除 registoBean.removeCtg(ct); // 返回导航结果,这里的字符串要和你配置的导航规则对应,或者直接写页面路径 return "ApagarCategoria?faces-redirect=true"; }
方案二:用void方法(刷新当前页面)
如果只是想删除后刷新当前的数据表格,不需要跳转页面,可以把方法改成void类型,删除后重新加载分类列表:
public void deleteCtg(Categorias ct) { registoBean.removeCtg(ct); // 重新加载分类列表,确保页面上的dataTable能显示最新数据 this.categoriasList = registoBean.getCategoriasList(); // 假设你有这个获取列表的方法 }
3. 调整EJB的删除方法
你的RegistoBean.java里的removeCtg方法返回List<Categorias>其实没必要,删除操作只需要确保数据被正确删除即可,建议改成void:
public void removeCtg(Categorias ct) { // 注意:如果传入的ct是游离状态(detached),需要先merge再remove if (!em.contains(ct)) { ct = em.merge(ct); } em.remove(ct); }
4. 确认页面按钮的绑定
检查ApagarCategoria.xhtml里的删除按钮,确保动作绑定正确,比如:
<h:dataTable value="#{registarVendedor.categoriasList}" var="c"> <!-- 其他列 --> <h:column> <h:commandButton value="Delete" action="#{registarVendedor.deleteCtg(c)}" /> </h:column> </h:dataTable>
做完这些调整后,再测试删除操作,应该就不会出现导航案例匹配失败的报错了。
内容的提问来源于stack exchange,提问作者Vales

