在我们公司,我们遇到了一个严重的问题,我们认为这是JSF规范的一个严重的设计缺陷,如果它是正常的行为。
这是我们的用例:
只要selectOneMenu的 value 属性中的实体使用与selectItems中的实体相同的entityManager加载,一切都按预期工作。我们有相同的POJO,因此相同的哈希码(Object#equals()返回true)。但是只要其中一个实体通过不同的entityManager加载并因此具有不同的哈希码,我们就永远无法获得匹配以生成选择项的预期选择的属性(HTML<选项/>)。
这种行为的原因是,JSF-impl和primefaces都在调用中使用POJO
boolean selected = isSelected(context, menu, itemValue, valuesArray, converter);
表示itemValue和valuesArray。 isSelected 的实现依赖于POJO的Object#equals()。在我看来,如果我们有一个转换器并将其传递给 isSelected ,它应该始终使用Converter#getAsString的值。这也是POST请求的行为。这里我们得到一个selectOneMenu的submittedValue,它与POJO的转换值(Converter#getAsString)进行比较。
现在问题 : 这是规范中描述的预期行为吗?转换器的输出不是处理这种比较的更好方法吗?现在我们必须修改我们的实体类并覆盖equals方法以便能够使用这个构造。
答案 0 :(得分:3)
您的错误是您忘记实施/自动生成equals()
(和hashCode()
)方法符合合同。这超出了JSF的控制范围。指责指责JSF没有任何意义。
拥有一个所有实体扩展的基础实体非常方便,因此您无需在所有实体上重复任务(即使普通的IDE /工具可以轻松自动生成它们)。您可以在第二个“另请参见”链接中找到一个精心设计的示例。
答案 1 :(得分:0)
我相信这是正确的行为。在Java端,组件和选择的值是POJO。你可以完全控制它们的平等等逻辑。它应该如何转换为UI显示和返回。作为组件用户,您不必费心去了解POJO的显示方式。作为文字,图标,颜色等等。组件的Java端未定位并与POJO进行通信
YOUR CODE ----------> JAVA COMPONENT --------> CONVERTER ----------> HTML
此外,我认为依靠实体的引用平等是解决问题的途径。将equals / hashCode设置为使用实际ID是最好的方法。