DateTimePicker<LocalDateTime> binding to ZonedDateTime with a custom converter is not working?

I have a field for a DateTimePicker called created

    private DateTimePicker created;

This is bound to a DTO class which has a ZonedDateTime property called created

binder = new CollaborationBinder<>(PostmortemDto.class, userInfo);
        binder.forField(created).withConverter(new ZonedDateTimeConverter());

This my implementation of ZonedDateTimeConverter


public class ZonedDateTimeConverter implements Converter<LocalDateTime, ZonedDateTime> {

    private ZoneId zoneId;

    /**
     * Creates a new converter using the given time zone.
     *
     * @param zoneId the time zone to use, not <code>null</code>
     */
    public ZonedDateTimeConverter(ZoneId zoneId) {
        this.zoneId = Objects.requireNonNull(zoneId, "Zone identifier cannot be null");
    }

    public ZonedDateTimeConverter() {
        this.zoneId = ZonedDateTime.now().getZone();
    }

    @Override
    public Result<ZonedDateTime> convertToModel(LocalDateTime localDate, ValueContext context) {
        if (localDate == null) {
            return Result.ok(null);
        }
        return Result.ok(ZonedDateTime.of(localDate, zoneId));
    }

    @Override
    public LocalDateTime convertToPresentation(ZonedDateTime zonedDateTime, ValueContext context) {
        if (zonedDateTime == null) {
            return null;
        }

        return zonedDateTime.toLocalDateTime();
    }
}

However it is not working, it throws the error relating to binding and incompatible types

Caused by: java.lang.IllegalStateException: Property type ‘java.time.ZonedDateTime’ doesn’t match the field type ‘java.time.LocalDateTime’. Binding should be configured manually using converter.
at com.vaadin.flow.data.binder.Binder.bindProperty(Binder.java:3320)
at com.vaadin.flow.data.binder.Binder.lambda$bindInstanceFields$25(Binder.java:3190)
at com.vaadin.flow.data.binder.Binder.handleProperty(Binder.java:3426)

Any ideas what I have done wrong?

Remove .class from the Binder constructor

Hmm, it requires two args

public CollaborationBinder(Class<BEAN> beanType, UserInfo localUser) {

Should I put the instance of the bean in there?

Interesting… looks like the CollabBinder doesn’t support all kind of stuff that the normal Binder has to offer. Looks like you either have to change your DTO or make the ZonedDateTimeConverter auto applicable

Thanks, any documentation on auto applicable. My google-fu couldn’t find anything about it

https://cookbook.vaadin.com/custom-binder-converter-factory

What about registering a converter, I see in the Vaadin codebase they register default converters. I wonder if I can extend that?

That’s exactly what this cookbook does with ConverterFactory