9

Possible Duplicate:
using Hibernate Validator without calling annotation.

I have this composite constraint annotation (only for illustration):

@Target... @Retention...
@Constraint(validatedBy = {})
@Pattern(regexp = PasswordComplexity.AT_LEAST_TWO_NONE_ALPAH_CHARS)
@Length(min = 6, max = 20)
public @interface PasswordComplexity {   
    ...    
}

And I use it in Spring Controllers and Entity Classes.

But now I need to check a single String in a Service method, where I need to apply the same constraint to a single String. Because of the fact that the constraint is the same, I want to use the same definition of the constraint (@PasswordComplexity) (single source of truth). Something like:

public void createUser(UserDto userDto, String password) {
  if(hasViolation(validator.validate(password,PasswordComplexity.class))) {
   throw new PasswordComplexityViolationException();
  } else {
   …
  }
}

But I do not know how to run the JSR 303 Validator for an not annotated simple object (String). Is it at least possible, and how?

(I use Hibernate Validator as JSR 303 provider)

Community
  • 1
  • 1
Ralph
  • 118,862
  • 56
  • 287
  • 383
  • I understand by 'single source of truth' you've meant not to have to repeat your annotation which is probably placed over `password` property/field in your `UserDto` class, right? But in your "something like" example you at least repeat the name of the annotation (`PasswordComplexity`). Isn't it a redundancy too? – Grzegorz Oledzki Jun 10 '11 at 09:08
  • @Grzegorz Oledzki: no the problem is not to write use the annotation in different places. With 'single source of truth' I mean I want to use the annotation instead of writing the same things (length and pattern) definition again somewhere else. – Ralph Jun 10 '11 at 09:56
  • @abalogh: The question is a duplicate (I have overlocked it), but the accepted answer did not match the question - or at least not my question. – Ralph Jun 10 '11 at 10:10
  • @Raplh: I see. Could you elaborate why did not the answer there match your needs? Following the suggestion there, you would have to create a (empty) instance of `UserDto`, populate its `password` property and fire validation on the single property. Why isn't it an option for you? 1. Is it because you have other validation constraints and you would want to validate the `@PasswordComplexity` only? 2. Or is more about not wanting to create a dumb instance of `UserDto`? – Grzegorz Oledzki Jun 10 '11 at 11:07
  • 1
    @Grzegorz Oledzki: because the UserDto has no password field. (and will not have any). So what I could do is create PasswordDto with a field password, annotated by @PasswordComplexity; create this PasswordDto in my service method from the password String parameter and then check it. -- Yes this will work, but this is a Hack and not clean code. -- I am searching for a clean, lean, straigth forward solution. – Ralph Jun 10 '11 at 11:16
  • I don't know why is this closed. The suggested duplicate doesn't give an answer to this problem either - the problem is not about programmatically validating beans but values. – yclian Jun 29 '11 at 03:19
  • @yclian: I agree, I worked with the accepted answer, because I did not find any other good solution. Anyway feel free to create a new question, and explain in this question what the difference to the other questions is. – Ralph Jun 29 '11 at 05:47

1 Answers1

2

One way to do this would be write a full custom validator, and push the logic down into that class having the annotation just use the validator. This would mean you then had an independent compilation unit (A full class PasswordComplexityValidator implements implements ConstraintValidator<PasswordComplexity, String> ...) which you could use independently of the annotation. This approach would also make it easier for you to unit test the validation.

However, since you are using the annotation as a way of configuring the existing regex validator provided by Hibernate, you could use that one instead, passing it the constant pattern from the annotation class. You should also be able to package your length constrain into the regex too, which would be simpler and faster than having both annotations anyway.

Simon Elliston Ball
  • 4,375
  • 1
  • 21
  • 18