在 EBean 和表单中保存枚举列表

Saving a list of enums in an EBean and a Form

我有一个包含枚举项的字段 'roles'。我正在尝试使用表单编辑此列表,但得到:

[InvalidPropertyException: Invalid property 'roles[0]' of bean class [models.Device]: Property referenced in indexed property path 'roles[0]' is neither an array nor a List nor a Map; returned value was [SERVER]]

这是我的实体:

@Entity
public class Device extends Model {

    @Id
    @Constraints.Min(1)
    public Long id;

    @Constraints.Required
    public String name;

    @Constraints.Required
    public String ipAddress;

    @Constraints.Required
    @ElementCollection(fetch = FetchType.EAGER)
    public Set<DeviceRole> roles = new HashSet<DeviceRole>(Arrays.asList(DeviceRole.OTHER));

    @Version
    public Timestamp lastUpdate;

    public static Finder<Long,Device> find = new Finder<Long,Device>(
      Long.class, Device.class
    );

    public List<ValidationError> validate() {
        /*
        List<ValidationError> errors = new ArrayList<ValidationError>();
        if (User.byEmail(email) != null) {
            errors.add(new ValidationError("email", "This e-mail is already registered."));
        }
        return errors.isEmpty() ? null : errors;
        */
        return null;
    }
}

控制器中的编辑和更新功能:

public static Result edit(Long id) {
    Device device = Device.find.byId(id);
    Form<Device> myForm = Form.form(Device.class);
    myForm = myForm.fill(device);

    return ok(views.html.Devices.edit.render(myForm, listOfRoles()));
}

public static Result update() {
    Form<Device> deviceForm = Form.form(Device.class).bindFromRequest();

    if (deviceForm.hasErrors()) {
        return badRequest(views.html.Devices.edit.render(deviceForm, listOfRoles()));
    }

    // Form is OK, has no errors, we can proceed
    Device device = deviceForm.get();
    device.update(device.id);
    return redirect(routes.Devices.index());
}

private static List<String> listOfRoles() {
    List<String> list = new ArrayList<String>();
    for(DeviceRole role : DeviceRole.values()) {
        list.add(role.toString());
    }
    return list;
}

和模板:

@main("Edit a device") {

  @helper.form(action = routes.Devices.update()) {
      @helper.inputText(myForm("name"))
      @helper.inputText(myForm("ipAddress"))

      @helper.select(myForm("roles"), options(deviceRoles), 'multiple->"multiple")

      <input type="hidden" name="id" value="@myForm("id").value">
      <input type="submit" value="Submit">
  }

  <a href="@routes.Devices.index()">Cancel</a>
}

实际上,这样做可能需要将它们保存为字符串字段中以逗号分隔的值列表,为了更清楚,我建议将 DeviceRole 更改为 Ebean 模型并处理它作为常见的 ManyToMany 关系。

恕我直言,它为您提供了更大的灵活性,还允许您在未来创建更多动态角色,

刚刚分叉了您的示例并对其进行了修改以展示我自己是如何做的(自述文件中的一些细节):

https://github.com/biesior/temperature-control

P.S.: 如果到现在为止没有任何变化,请查看 Ebean 的票证,只是尚不支持保存枚举列表(我不知道当前状态)http://avaje.org/topic-149.html

对于 Enum,您可以使用 @EnumValue,这是 Ebean 特定的注释,用于将 Enum 映射到数据库值。

public static enum RoleName {
  @EnumValue("SERVER") SERVER,
  @EnumValue("TEMPERATURE") TEMPERATURE,
  @EnumValue("HUMIDITY") HUMIDITY,
  @EnumValue("SWITCH") SWITCH,
  @EnumValue("OTHER") OTHER
}

参考:http://ebean-orm.github.io/docs/mapping/#enummapping