Bean Validation on method
Asked Answered
J

2

7
public class Register {
    @NotNull private String password;
    @NotNull private String passwordRepeat;
    @AssertTrue private boolean comparePasswords() { 
       return password.equals(passwordRepeat);
    }

    private Set<ConstraintViolation<Register>> violations;

    public void doRegister(AjaxBehaviorEvent event) {
        Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
        violations = validator.validate(this);

        if(violations.isEmpty()) {
            // This occurs
        }
    }
}

My validation will pass if both my passwords are not null, but they are different. Seems like the last constraint will not be taken into account, though I do not have a clue why. Does anyone have suggestion?

And no, I am not searching for any implementations of @Matches or simular custom validators. I just would like to get this problem solved.

Thanks in advance.

Update 1

I have run some tests regarding this, hopefully the results will provide needed information.

Bean.java

@Named
@RequestScoped
public class Bean {
    @NotNull private String example1;
    @NotNull private String example2;
    @AssertTrue private boolean examplesMatch() { return example1.equals(example2); }

    private Set<ConstraintViolation<Bean>> violations;
    private FacesContext context;
    private Validator validator;

    @PostConstruct
    public void init() {
        context = FacesContext.getCurrentInstance();
        validator = Validation.buildDefaultValidatorFactory().getValidator();

        example1 = "abc";
        example2 = "def";
        runValidation(false, 1);

        example1 = "abc";
        example2 = "abc";
        runValidation(true, 2);

        example1 = "abc";
        example2 = null;
        runValidation(false, 3);
    }

    private void runValidation(boolean assertion, int testNr) {
        FacesMessage message;
        violations = validator.validate(this);
        if(violations.isEmpty() == assertion) {
            message = new FacesMessage("Passed test nr. " + testNr);
        }
        else {
            message = new FacesMessage("Failed test nr. " + testNr);
        }
        context.addMessage(FacesMessage.FACES_MESSAGES, message);
    }

index.xhtml

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
    <head>
        <title>TODO supply a title</title>
    </head>
    <body>
        #{bean}
        <h:messages />
    </body>
</html>

Result

beanvalidation.Bean@31c5c3da

    Failed test nr. 1
    Passed test nr. 2
    Passed test nr. 3 
Jural answered 17/10, 2012 at 13:24 Comment(4)
Why use annotations. just have the boolean method , inside which you can have the null check, then inside the null check compare the two strings .Marsden
what validation mode are you using?Pristine
@TheDarkKnight Because this is just a relevant sample of a larger class.Jural
@Pristine I have no ValidationMode defined, so I guess it will default to AUTO? I am currently implementing it using Validator validator = Validations.buildDefaultValidatorFactory().getValidator; violations = validator.validate(this);Jural
K
34

examplesMatch() is not a valid Java Beans boolean property getter. It needs to start with get or is.

Krissy answered 18/10, 2012 at 8:45 Comment(2)
in addition to is and get, starting the method with has also appears to work.Monogyny
This answer is still relevant in 2023; crazy the documentation doesn't reflect this in a top level place around AssertTrueMagnesia
L
0

@BalusC gives a great answer as usual!

Note also: in this brave new world of the jakarta.validation namespace versus javax.validation, in my case I was importing AssertTrue from the former but my container (WildFly 26) was only recognising the latter.

Landeros answered 24/2, 2022 at 7:15 Comment(1)
BalusC just edited the post :))Photoperiod

© 2022 - 2024 — McMap. All rights reserved.