Search code examples
javavalidationbean-validationhibernate-validator

Append type level validation error message to specific field


I've got a simple class which get's validated using the boolean isValid() method, which works and of course the error message is at class/type level.

Here's my simple class:

public class NewPasswordDTO {
    @NotNull
    public String password;

    @NotNull
    public String confirmation;

    @AssertTrue(message="Passwords must match.")
    protected boolean isValid() {
        return password.equals(confirmation);
    }
}

But what I really want is something like that:

public class NewPasswordDTO {
    @NotNull
    @Equals("confirmation", message="...")
    public String password;

    @NotNull
    public String confirmation;
}

So the error message would be set at field level and not at class/type level.

Is this possible somehow? Maybe using a custom Validator for that class?

Thanks in advance!

SOLUTION:

Thanks to Gunnar! I've just came up with a nice, universal solution :-). I simply used (means copy & paste) the code from Hibernates @ScriptAssert and ScriptAssertValidator and modified it slightly:

@ScriptAssert:

  • Add new String field(). (this is where the error message gets appended)

ScriptAssertValidator:

  • Inside the initialize method, make sure to also save the fieldName and message properties, because we need to access them in the next step

  • Add this snippet at the bottom of isValid method:

    context.buildConstraintViolationWithTemplate(errorMessage) .addPropertyNode(fieldName).addConstraintViolation();

  • Also add context.disableDefaultConstraintViolation(); somewhere inside the isValid method to not generate the default error message which else would get appended at class level.

And that's it. Now I can use it like that:

@FieldScriptAssert(lang="javascript", script="_this.password.equals(_this.confirmation)", field="password", message="...")
public class NewPasswordDTO { ... }

Solution

  • Simple answer : It is not (unless you implement it) :http://docs.oracle.com/javaee/6/api/javax/validation/constraints/package-summary.html shows all annotation constraints. Of course you could inject your string as a resource in your class by @producer and so on (which recently is discussed to be removed in jdk8), but you could not use this value for your assert.
    In reply to the comment:
    This was asuming that the nature is a constant string which you would like to use as a string resource.And then of course it is possible to write your own class based on java.lang.string with a @Producer which is then @Inject - able. Though it is certainly not the way I personally would deal with constant strings.