我在使用<s:convertEntity />当我提交表单时,在页面 /Value is not a valid option/ 上收到错误消息 - 我做错了什么?
在Seam论坛上经常被询问的问题总是无法解决 - 让我们分析一下这个问题,看看解决方案,以及需要修改JSF才能使其消失的更改。
背景
JSF允许您为任何可编辑值指定转换器;转换器在渲染页面时将 /从/ 对象 /转换为/ 字符串,在提交表单时 /从/ 字符串 /转换为/ 对象。JSF自带一些内置转换器(例如,用于日期、枚举...)或允许您创建自定义转换器。对象/到/字符串当提交表单时,/从/字符串/到/对象当提交表单时,您使用它来获取并返回它。日期, 枚举...)或允许您创建一个自定义转换器。
在您的自定义转换器中,您实现getAsString, 返回一个字符串, 当传递到getAsObject时,您使用它来获取并返回它。对象对象
Seam提供<s:convertEntity />, 一个通用转换器,它可以转换任何JPA实体(使用注解或XML映射,具有简单或复合键)。它存储实体的主键,返回键存储位置的引用;当页面提交时,从存储中获取键并用于加载实体。
问题
JSF 1.2规范(第4.1.15.3和4.1.16.3节)指定
...必须提供一个专门的validate()方法,以确保任何解码的值是有效的选项(来自嵌套的UISelectItem和UISelectItems子项)。
换句话说,提交的条目必须列在页面显示的列表中。因为实体转换器在页面提交时从持久化上下文中加载选定的对象,所以提交的对象不在显示的列表中。
解决方案
- 在同一长会话中显示列表并提交表单(这样持久化上下文两次都会返回同一个对象)。这使得缓存可选择的项列表变得困难。
- 覆盖equals()在实体上(这不是一个好主意)。
解决方案
对于JSF 2,这个验证应该是可选的/可覆盖的(正如它在其他地方的JSF中一样)。在这种情况下,转换器正在执行所有必要的验证。