Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
350 views
in Technique[技术] by (71.8m points)

Vaadin 14 - How to allow null values in form validation

Part of an application I'm writing is an "editor" form for a task. Some of the task entity fields can be null, for example: date completed.

I'm using a Binder to bind the entity fields to the editor fields and also perform validation. I'm running into an issue where validation fails because items (like date completed) are null. It's OK for this to be null. However, the field is flagged as "value null" and the entity is not saved.

Is there a way to tag what are essentially optional fields so that nulls are allowed? Of course, if a value has been entered, then it needs to be validated.

Task.java (the entity)

@Entity
public class Task extends AbstractEntity {

  ...
  // These are optional fields.
  private Long           dateDue;
  private Long           dateStarted;
  private Long           dateCompleted;
  ...
}

EditTaskForm.java

public class EditTaskForm extends VerticalLayout {

  private DatePicker                  dateDue;
  private DatePicker                  dateStarted;
  private DatePicker                  dateCompleted;
  ...
  
  private void bindData() {
    binder = new Binder<>(Task.class);

    ...
    binder.forField(dateDue)
      .withConverter(new LocalDateToLongConverter())
      .bind("dateDue");

    binder.forField(dateStarted)
      .withConverter(new LocalDateToLongConverter())
      .bind("dateStarted");

    binder.forField(dateCompleted)
      .withConverter(new LocalDateToLongConverter())
      .bind("dateCompleted");
    
    binder.withValidator(new TaskValidator());
  }

  private void validateAndSave() {
    try {
      binder.writeBean(task);
      fireEvent(new SaveEvent(this, task));
    } catch (ValidationException e) {
      logger.error("field validation errors:");
      e.getFieldValidationErrors().forEach(er -> {
        logger.error("status: {}", er.getStatus());
        logger.error("message: {}", er.getMessage().get());

        logger.error("field: {}", er.getField().getValue());
      });

      logger.error("bean validation errors:");
      e.getBeanValidationErrors().forEach(er -> {
        logger.error(er.getErrorMessage());
      });
    }
  }
  
  ...
}

If I run the application, create a new task, don't specify a value for any of those optional fields and attempt to validate and save, each field on the form is flagged with the message "value null" and highlighted.

UPDATE:

It turns out the "value null" was coming from the LocalDateToLongConverter. Here it is (note the commented out code):

public class LocalDateToLongConverter implements Converter<LocalDate, Long> {

  private ZoneId            zoneId;

  public LocalDateToLongConverter(ZoneId zoneId) {
    this.zoneId = Objects.requireNonNull(zoneId, "Zone id cannot be null");
  }

  public LocalDateToLongConverter() {
    this(ZoneId.systemDefault());
  }

  @Override
  public Result<Long> convertToModel(LocalDate value, ValueContext context) {
    if (value != null) {
      return Result.ok(Date.from(value.atStartOfDay(zoneId).toInstant()).getTime());
    } else {
      return Result.ok(null);
      // return Result.error("value null");
    }
  }

  @Override
  public LocalDate convertToPresentation(Long value, ValueContext context) {
    if (value != null) {
      return Instant.ofEpochMilli(value).atZone(zoneId).toLocalDate();
    } else {
      return null;
    }
  }

}
question from:https://stackoverflow.com/questions/66064518/vaadin-14-how-to-allow-null-values-in-form-validation

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

While the description is a little unclear and the code example isn't comprehensive enough for me to try it out, I still have a strong suspicion about what happens.

The text "value null" does not originate from Binder itself nor any other part of Vaadin. Instead, it's most likely produced by the custom LocalDateToLongConverter implementation. I would thus recommend that you review its implementation to see if that's what causes the fields to be marked as invalid.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...