Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I change annotations/Hibernate validation rules at runtime?

If have a Java class with some fields I want to validate using Hibernate Validator. Now I want my users to be able to configure at runtime which validations take place.

For example:

public class MyPojo {
    ...

    @NotEmpty
    String void getMyField() {
        ... 
    }

    ...
}

Let's say I want to remove the NotEmpty check or replace it with Email or CreditCardNumber, how can I do it? Is it even possible? I guess it comes down to changing annotations at runtime...

like image 859
Daniel Rikowski Avatar asked Apr 15 '09 09:04

Daniel Rikowski


2 Answers

You can't do it normally.

Here's what I've done to get more dynamic validations working via Hibernate Validator.

  1. Extend the ClassValidator class.
  2. Override the getInvalidVaues(Object myObj) method. First, call super.getInvalidValues(myObj), then add the hook to your customized validation.
  3. Instantiate your custom validator and call getInvalidValues to validate. Any hibernate annotated validations will kick off at this point, and your custom dynamic validations (anything not supported by annotations) will kick off as well.

Example:

public class MyObjectValidator extends ClassValidator<MyObject>
{
    public MyObjectValidator()
    {
         super(MyObject.class);
    }

    public InvalidValue[] getInvalidValues(MyObject myObj)
    {
        List<InvalidValue> invalids = new ArrayList<InvalidValue>();
        invalids.addAll(Arrays.asList(super.getInvalidValues(myObj)));

        // add custom validations here
        invalids.addAll(validateDynamicStuff(myObj));

        InvalidValue[] results = new InvalidValue[invalids.size()];
        return invalids.toArray(results);
    }

    private List<InvalidValue> validateDynamicStuff(MyObject myObj)
    {
        // ... whatever validations you want ...
    }

}

So your custom validation code can contain logic like "Do this validation, if the user configured it, otherwise do that one", etc. You may or may not be able to leverage the same code that powers the hibernate validations, but either way, what you are doing is more involved that the 'normal' use case for hibernate validator.

like image 141
Justin Standard Avatar answered Oct 18 '22 09:10

Justin Standard


Actually it is possible in hibernate validator 4.1. Just read the documentation about programatic constraint creation.

like image 45
Pma Avatar answered Oct 18 '22 09:10

Pma