Skip to content

BeanValidationBinder reports valid even though using validation API directly reports invalid #9453

@mstahv

Description

@mstahv

Vaadin 8

Repeatable with following example code:

public class MyUI extends UI {

    public static class Entity {

        @NotNull
        //@Size(min = 3, max = 10)
        private String name;

        public void setName(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        @Override
        public String toString() {
            return "Entity, name: " + name;
        }

    }

    final TextField name = new TextField();

    @Override
    protected void init(VaadinRequest vaadinRequest) {

        final VerticalLayout layout = new VerticalLayout();
        name.setCaption("Type your name here:");

        Entity entity = new Entity();
        Binder<Entity> b = new BeanValidationBinder<>(Entity.class);
        //b.forMemberField(name).withNullRepresentation(""); // This seems to fix the issue
        b.bindInstanceFields(this);

        b.setBean(entity);

        Button button = new Button("Check validity");
        button.addClickListener(e -> {
            ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
            Validator validator = factory.getValidator();
            Set<ConstraintViolation<Entity>> validate = validator.validate(entity);
            String msg = String.format("Binder.isValid: %s, JSR 303 valid: %s, name: %s", b.isValid(), validate.isEmpty(), entity.getName());
            Notification.show(msg);
        });

        layout.addComponents(name);
        layout.addComponent(button);

        setContent(layout);
    }

    @WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
    @VaadinServletConfiguration(ui = MyUI.class, productionMode = false)
    public static class MyUIServlet extends VaadinServlet {
    }
}

It took me long to realise what was wrong, but BeanValidationBinder seems to do the validation over the field value instead of the actual bean state, even though "non-buffered mode" (setBean method) is used. This "functionality" makes odd situations when invalid stuff from UI is passed to the backend and the UI developer would expect that it could never happen.

Metadata

Metadata

Assignees

No one assigned

    Labels

    StaleStale bot label

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions