frog_in_the_fog
frog_in_the_fog

Reputation: 11

How to validate using all annotations with single Jakarta/Hibernate validator?

I'm using Jakarta/Hibernate to validate some fields in Java.

The problem is the data model is generated from Swagger file thus all the Jakarta annotations like @Size or @Pattern are autogenerated.

I cannot change the Swagger to generate some custom annotations but I have to create one single validation message based on all the constraints/annotations assigned to particular field.

My idea is to implement custom MessageInterpolator. I can get default interpolator using HibernateValidatorConfiguration class and set up constraint mapping:

 constraintMapping.constraintDefinition(->annotation here<-)
.validateBy(MyValidator.class);

configurationHibernate.addMapping(constraintMapping)
.messageInterpolator(myInterpolator);

As you can see it can handle only one annotation but I want to write only one validator and only one interpolator for all the annotations at once to have min, max, pattern values and create a message based on them.

Is there any way to achieve such implementation to get all the available annotations from the particular field and create a message based on the available annotations?

It's worth to mention that one field can have @Size and @Pattern but another one could posses only @Size. For both class fields I want to use the same validator/message interpolator and create a message dynamically.

I know this is not the way Hibernate was designed so any other suggestions welcome. :)

I was trying to access the field and all available annotations by Jakarta validation Context class but with no success.

Upvotes: 1

Views: 309

Answers (1)

RanAbitbul
RanAbitbul

Reputation: 211

Assuming that although Swagger is the one generating the objects, you still have to read values and create POJOs out of them, you could use the jackson.databind.ObjectMapper for deserialization and javax.validation class to trigger the annotation validations.

public static <T> T deserialize(String serialized, Class<T> cls) throws JsonProcessingException {
  ObjectMapper mapper = new ObjectMapper();
  return mapper.readValue(serialized, cls);
}

public static <T> T deserializeAndValidate(String serialized, Class<T> cls) throws JsonProcessingException {
  T result = deserialize(serialized, cls);
  validateObject(result);   return result;
}

public static void validateObject(Object object) {
  ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
  Validator validator = factory.getValidator();
  Set<ConstraintViolation<Object>> violations = validator.validate(object, new Class[0]);
  if (!violations.isEmpty()) {
    throw new ValidationException(String.format("Validation failed for object of type '%s': %s", object.getClass().getName(), violations));
  }
}

Upvotes: 0

Related Questions