具有 SQL 日期的 DateField Vaadin 组件

DateField Vaadin Component with SQL Date

因此,我的 POJO class 中有一个 属性 SQL.Date。我想使用 Vaadin Component 中的 Binder 绑定它,但总是这样返回:

Property type 'java.sql.Date' doesn't match the field type 'java.time.LocalDate'. Binding should be configured manually using converter.

所以这是我的 Getter Setter 包含在 POJO class

public Date getDateOfBirth() {
    return dateOfBirth;
}

public void setDateOfBirth(Date dateOfBirth) { this.dateOfBirth = dateOfBirth; }

下面是我使用 Binder 组件的情况:

binder = new Binder<>(Person.class);
binder.bindInstanceFields( this );

仅供参考,我使用 Spring Boot JPA 作为数据。 Spring Boot?

报错信息和用法有关系吗

这个

Property type 'java.sql.Date' doesn't match the field type 'java.time.LocalDate'. Binding should be configured manually using converter.

告诉你该怎么做。没有看到你的代码,我假设你在一些 Vaadin FormLayout 中有 Vaadin DateField 你试图用 java.sql.Date 值填充(或 binder.bindInstanceFields() 尝试)。

可惜DateField似乎只接受LocalDate。因此,您需要以某种方式转换该值。

vaadin Converter 类型层次结构中有很多不同的 "date" 转换器,但缺少这个(或者我错过了?)所以我创建了它:

public class SqlDateToLocalDateConverter
       implements Converter<LocalDate,java.sql.Date> {
    @Override
    public Result<java.sql.Date> convertToModel(LocalDate value,
           ValueContext context) {
        if (value == null) {
            return Result.ok(null);
        }
        return Result.ok( java.sql.Date.valueOf( value) );
    }
    @Override
    public LocalDate convertToPresentation(java.sql.Date value,
           ValueContext context) {
        return value.toLocalDate();
    }
}

你好像用的是声明式ui?我现在无法告诉它如何毫不费力地移植它。

如果您手动绑定字段,它会像这样:

    binder.forField(myForm.getMyDateField())
       .withConverter(new SqlDateToLocalDateConverter())
       .bind(MyBean::getSqlDate, MyBean::setSqlDate);

所以我猜你需要找到一种方法来添加这个转换器来处理假定的 DateField。无论如何,消息表明您可能无法使用简单的方法 binder.bindInstanceFields(),而是手动绑定字段。

您可以创建自定义日期字段并使用它代替 DateField。然后你不需要每次都绑定它只需使用自动绑定

public class CustomDateField extends CustomField<Date> {
    DateField dateField;

    public CustomDateField(String caption) {
        setCaption(caption);
        dateField = new DateField();
        dateField.setDateFormat("dd/MM/yy");
    }

    @Override
    protected Component initContent() {
        return dateField;
    }

    @Override
    protected void doSetValue(Date date) {
        dateField.setValue(date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
    }

    @Override
    public Date getValue() {
        return dateField.getValue() != null ? Date.from(dateField.getValue().atStartOfDay(ZoneId.systemDefault()).toInstant()) : null;
    }
}