同一个 bean 的多个托管属性,在同一个 class

multiple managed properties of the same bean, in the same class

我需要解决这个业务需求,但我遇到了一些不想要的行为,我需要专家的帮助。 我正在使用 JSF 2.2.13、Prime Faces 5.3

我有一个这样的 UserBean

@ManagedBean(name = "userBean")
@RequestScoped
public class UserBean implements Serializable {
  private Long id;
  private String firstName;
  private String lastName;
  @ManagedProperty(value = "#{countryBean}")
  private CountryBean phoneCode1;
  private String phoneNumber1;
  @ManagedProperty(value = "#{countryBean}")
  private CountryBean phoneCode2;
  private String phoneNumber2;
...
...getter/setter

和这样的 CountryBean

@ManagedBean(name = "countryBean")
@RequestScoped
public class CountryBean implements Serializable{
  private Long id;
  private String isoCode;
  private String phoneCode;
  ...
  ...getter/setter

问题(正如您可能已经知道的那样)是在 UserBean 内部,我们有超过 1 个字段(phoneCode1,phoneCode2)的相同托管 属性(countryBean)。

奇怪的是,在数据库内部(MySQL),我的应用程序为所有这些字段(phoneCode1、phoneCode2)保存了相同的值,即使在前端我们select 不同的值。

在前端我有这段代码

<h:selectOneMenu value="#{userController.userBean.phoneCode1.id}" class="form-control">
    <f:selectItem itemLabel="#{msg['seleziona']}" itemValue="" noSelectionOption="true" />
    <f:selectItems value="#{applicationScopedBean.countries}" var="ac" itemValue="#{ac.id}" itemLabel="#{ac.phoneCode}"/>
 </h:selectOneMenu>
<h:selectOneMenu value="#{userController.userBean.phoneCode2.id}" class="form-control">
    <f:selectItem itemLabel="#{msg['seleziona']}" itemValue="" noSelectionOption="true" />
    <f:selectItems value="#{applicationScopedBean.countries}" var="ac" itemValue="#{ac.id}" itemLabel="#{ac.phoneCode}"/>
 </h:selectOneMenu>

那么,我们可以通过哪些方式来解决这个业务需求呢?

我看到过类似的问题,但我不明白是我没有很好地使用 JSF,还是 JSF 的限制。 从数据库的角度来看,它类似于询问 "In which way I can create a table named "A",其中一些 FK 链接到 table "B"?

谢谢!

代替 @RequestScoped,对 CountryBean 使用 @NoneScoped

None Scope

事实上,错误是在那种情况下没有理由使用注释@ManagedProperty。

当同一作用域中有超过 1 个实例时,使用 @ManagedProperty 是无用的。

@ManagedProperty 的目的是标识所用范围内唯一可用的实例。

我遇到的情况与您的情况非常相似,但有点复杂,因为我在 "Parent" bean 中以及在父 bean 中用作托管属性的 bean 中有多个相同 bean 的托管属性 I对其他 bean 有其他托管属性。这是因为所有这些 "child" bean 都绑定到前端元素并且需要可重用(基本上是一个 3 个下拉列表元素,用于询问用户他的房子地址、他的工作和其他额外位置)。问题是,当用户选择一个位置的地址时,值会在其他 3 个位置重复。

所以我对这个问题的解决方案是将所有 "child" bean(可重用的)设置为 @NoneScoped 并将 "parent" bean 设置为 @ViewScoped

这非常有效,每个位置的地址不再相互干扰。所有这一切在 "parent" bean 中仍然具有同一个 bean 的多个托管属性。

希望这对有类似问题的人有用。