10

I am looking at using Hibernate Validator for a requirement of mine. I want to validate a JavaBean where properties may have multiple validation checks. For example:

class MyValidationBean
{
   @NotNull
   @Length( min = 5, max = 10 )
   private String myProperty;
}

But if this property fails validation I want a specific error code to be associated with the ConstraintViolation, regardless of whether it failed because of @Required or @Length, although I would like to preserve the error message.

class MyValidationBean
{
   @NotNull
   @Length( min = 5, max = 10 )
   @ErrorCode( "1234" )
   private String myProperty;
}

Something like the above would be good but it doesn't have to be structured exactly like that. I can't see a way to do this with Hibernate Validator. Is it possible?

3 Answers 3

9

You could create a custom annotation to get the behaviour you are looking for and then on validating and using refelection you could extract the value of the annotation. Something like the following:

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ErrorCode {
    String value();
}

In your bean:

@NotNull
@Length( min = 5, max = 10 )
@ErrorCode("1234")
public String myProperty;

On validating your bean:

Set<ConstraintViolation<MyValidationBean>> constraintViolations = validator.validate(myValidationBean);    
for (ConstraintViolation<MyValidationBean>cv: constraintViolations) {
    ErrorCode errorCode = cv.getRootBeanClass().getField(cv.getPropertyPath().toString()).getAnnotation(ErrorCode.class);
    System.out.println("ErrorCode:" + errorCode.value());
}

Having said that I probably would question the requirements for wanting error codes for these types of messages.

Sign up to request clarification or add additional context in comments.

1 Comment

This is a great solution many thanks for posting. Just one thing to note.. The code should read getDeclaredField to enable it to access the private field.
3

From the section 4.2. ConstraintViolation of the specification:

The getMessageTemplate method returns the non-interpolated error message (usually the message attribute on the constraint declaration). Frameworks can use this as an error code key.

I think this is your best option.

1 Comment

Thanks for the reply. Unfortunately I don't think this will preserve the original error message, which I would like. I'm looking for an additional error code on top of this. Sadly looking at the API for ConstraintViolation I don't really see anything that looks promising.
0

What I would try to do is isolate this behavior on the DAO Layer of the application.

Using your example we would have:

public class MyValidationBeanDAO {
    public void persist(MyValidationBean element) throws DAOException{
        Set<ConstraintViolation> constraintViolations = validator.validate(element);
        if(!constraintViolations.isEmpty()){
            throw new DAOException("1234", contraintViolations);
        }
        // it's ok, just persist it
        session.saveOrUpdate(element);
    }
}

And the following exception class:

public class DAOException extends Exception {
private final String errorCode;
private final Set<ConstraintViolation> constraintViolations;

public DAOException(String errorCode, Set<ConstraintViolation> constraintViolations){
    super(String.format("Errorcode %s", errorCode));
    this.errorCode = errorCode;
    this.constraintViolations = constraintViolations;
}
// getters for properties here
}

You could add some annotation information based on what property has not validated from here, but always doing this on the DAO method.

I hope this helped.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.