如何从SelectOneMenu设置@ManyToOne注释字段?

时间:2014-12-01 05:00:03

标签: java-ee jsf-2.2 jpa-2.1

我有一个测试.xhtml布局文件

. . .
<h:form rendered="#{departmentBean.editEmployee}">
  Employee name
  <h:inputText id="fullName" value="#{departmentBean.employee.fullName}" />
  <h:selectOneMenu label="Department" value="#{departmentBean.employee.department}" converter="departmentConverter">
    <f:selectItems value="#{departmentBean.departmentList}" var="department" 
                   itemLabel="#{department.name}" itemValue="#{department}" />
  </h:selectOneMenu>
  <h:commandButton value="Save" action="#{departmentBean.save()}" />
</h:form>
. . .

另外,我有两个Entity classess:Employee and Department:

@Entity
@Table(name = "departments")
public class Department implements Serializable {

  @Id
  @Column(name = "dep_pcode")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private int id;

  @Column(name = "dep_name", nullable = false, length = 50)
  private String name;

  //. . . setters and getters
}

@Entity
@Table(name = "employee")
public class Employee implements Serializable {

  @Id
  @Column(name = "emp_pcode")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private int id;

  @Column(name = "emp_fullname", nullable = false, length = 128)
  private String fullName;

  @ManyToOne
  @JoinColumn(name = "emp_depcode")
  private Department department;

  // . . . Setters and getters
}

所以我需要通过网络表单在一些具体的员工中设置部门。要从SelectOneMenu组件转换输入值,反之亦然,我使用自定义转换器:

@FacesConverter("departmentConverter")
public class DepartmentConverter implements Converter {

  @EJB
  DepartmentEJB ejb;

  @Override
  public Object getAsObject(FacesContext context, UIComponent component, String value) {
    Department result = null;
    try {
        int id = Integer.parseInt(value);
        result = ejb.get(id);
    } catch (Exception e) {
      throw new ConverterException("Can't convert into Department string value: " + value);
    }
    return result;
  }

  @Override
  public String getAsString(FacesContext context, UIComponent component, Object value) {
    if (value instanceof Department) {
      return ((Department) value).getId() + "";
    }
    throw new ConverterException("Can't use departmentConverter for " + value.getClass().getName());
  }
}

但是,提交表单时,我看到验证错误消息。

&#34;部门:验证错误:值无效&#34;。

我为Department类编写了自定义验证器

@FacesValidator("departmentValidator")
public class DepartmentValidator implements Validator {

  @Override
  public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
    if ((value instanceof Department)) {
      Department dep = (Department)value;
      if (dep.getId() == 0) {
        FacesMessage msg = new FacesMessage("Department's id = 0!",
                "Department validation failed.");
        msg.setSeverity(FacesMessage.SEVERITY_ERROR);
        throw new ValidatorException(msg);
      }
    } else {
        FacesMessage msg = new FacesMessage("Can't validate " + value.getClass().getName() + " as Department ",
                "Department validation failed.");
        msg.setSeverity(FacesMessage.SEVERITY_ERROR);
        throw new ValidatorException(msg);
    }
  }
}

我确信部门的验证值id实例。但我仍然得到验证错误,表示该值无效。

我可以在某处详细说明如何正确设置souch字段的值吗?我错过了什么?

感谢您的回答并浪费您的时间。最好的问候。

1 个答案:

答案 0 :(得分:0)

作为临时解决方案,我使用下面的内容:

  1. 在Employee类中创建@Transient字段(departmentCode);
  2. 制作@PostLoad方法,该方法将链接的Department实例的id读入 departmentCode;
  3. 在.xhtml表单中,设置departmentCode的值而不是department;
  4. 在Managed Bean的save()方法中,通过departmentCode值获取Department实例;
  5. 将获取的Department实例设置为Employee的department属性;
  6. 那么,任何人都知道更简单的方法吗?