Компонент DateField Vaadin с датой SQL

Итак, у меня есть свойство SQL.Date в моем классе POJO. Я хочу связать его с помощью Binder из Vaadin Component, но всегда возвращался так:

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

Итак, вот мой Getter Setter, содержащийся в классе POJO

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?


person Aroli Marcellinus    schedule 12.11.2017    source источник
comment
Какая версия? Vaadin8?   -  person pirho    schedule 12.11.2017
comment
да, Ваадин 8.0.0   -  person Aroli Marcellinus    schedule 13.11.2017
comment
Если вы не предоставляете полную трассировку стека, трудно сказать, какая библиотека его вызывает.   -  person Jens Schauder    schedule 11.01.2018


Ответы (2)


Этот

Тип свойства java.sql.Date не соответствует типу поля java.time.LocalDate. Привязку нужно настраивать вручную с помощью конвертера.

говорит что делать. Не видя вашего кода, я предполагаю, что у вас есть Vaadin DateField в каком-то Vaadin FormLayout, который вы пытаетесь заполнить значением java.sql.Date (или binder.bindInstanceFields() попыток).

К сожалению, DateField, похоже, принимает только LocalDate. Следовательно, вам нужно как-то преобразовать значение.

В иерархии типов vaadin Converter есть много разных конвертеров "даты", но этот отсутствует (или, может быть, я его пропустил?), Поэтому я его создал:

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();
    }
}

Кажется, вы пользуетесь декларативным интерфейсом? Я не могу сейчас сказать, как портировать это с небольшими усилиями.

Если бы вы связывали поля вручную, это выглядело бы так:

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

Итак, я думаю, вам нужно найти способ добавить этот конвертер для обработки предполагаемого DateField. В любом случае сообщение предполагает, что вы, возможно, не сможете использовать простой binder.bindInstanceFields() способ, а привязать поля вручную.

person pirho    schedule 12.11.2017
comment
ааа ладно. спасибо за объяснение, а также за исходный код конвертера. Действительно ценю это - person Aroli Marcellinus; 15.11.2017

Вы можете создать настраиваемое поле даты и использовать его вместо 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;
    }
}
person ensarg    schedule 30.01.2018
comment
ого. Я только что понял, что мы можем создать собственный класс в Ваадине. Спасибо за ответ. - person Aroli Marcellinus; 26.02.2018