如何从选择菜单设置@ManyToOne注释字段



我有一个测试.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
@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());
  }
}

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

"部门:验证错误:值无效"。

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

@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字段值的详细示例吗?我错过了什么?

感谢您的回答,并为我浪费时间。此致敬意。

作为临时解决方案,我使用Folowing:

  1. 在员工类中制作@Transient字段(部门代码);
  2. make @PostLoad方法,该方法将链接部门实例的 ID 读取到部门代码;
  3. 在.xhtml窗体中,设置部门代码而不是部门代码的值;
  4. 在托管Bean的save()方法中,通过部门代码值获取部门实例;
  5. 将提取的部门实例设置为员工的部门属性;

那么,有人知道更简单的方法吗?

最新更新