Hibernate Validator and Jackson: Using the @JsonProperty value as the ConstraintViolation PropertyPath?

Unfortunately there is no easy way to do it. But here are some insights that can help you:

Parsing constraint violations

From the ConstraintViolationException, you can get a set of ConstraintViolation, that exposes the constraint violation context:

  • ConstraintViolation#getLeafBean(): If it is a bean constraint, this method returns the bean instance in which the constraint is applied to.
  • ConstraintViolation#getPropertyPath(): Returns the path to the invalid property.

From the property path, you can get the leaf node:

Path propertyPath = constraintViolation.getPropertyPath();
Optional<Path.Node> leafNodeOptional = 
        StreamSupport.stream(propertyPath.spliterator(), false).reduce((a, b) -> b);

Then check if the type of the node is PROPERTY and get its name:

String nodeName = null;

if (leafNodeOptional.isPresent()) {
    Path.Node leafNode = leafNodeOptional.get();
    if (ElementKind.PROPERTY == leafNode.getKind()) {
        nodeName = leafNode.getName();
    }
}

Introspecting a class with Jackson

To get the available JSON properties from the leaf bean class, you can introspect it with Jackson (see this answer and this answer for further details):

Class<?> beanClass = constraintViolation.getLeafBean().getClass();
JavaType javaType = mapper.getTypeFactory().constructType(beanClass);

BeanDescription introspection = mapper.getSerializationConfig().introspect(javaType);
List<BeanPropertyDefinition> properties = introspection.findProperties();

Then filter the properties by comparing the leaf node name with the Field name from the BeanPropertyDefinition:

Optional<String> jsonProperty = properties.stream()
        .filter(property -> nodeName.equals(property.getField().getName()))
        .map(BeanPropertyDefinition::getName)
        .findFirst();

Using JAX-RS?

With JAX-RS (if you are using it), you can define an ExceptionMapper to handle ConstraintViolationExceptions:

@Provider
public class ConstraintViolationExceptionMapper 
                 implements ExceptionMapper<ConstraintViolationException> {

    @Override
    public Response toResponse(ConstraintViolationException exception) {
        ...
    }
}

To use the ObjectMapper in your ExceptionMapper, you could provide a ContextResolver<T> for it:

@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {

    private final ObjectMapper mapper;

    public ObjectMapperContextResolver() {
        mapper = createObjectMapper();
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return mapper;
    }

    private ObjectMapper createObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        return mapper;
    }
}

Inject the Providers interface in your ExceptionMapper:

@Context
private Providers providers;

Lookup for your ContextResolver<T> and then get the ObjectMapper instance:

ContextResolver<ObjectMapper> resolver = 
        providers.getContextResolver(ObjectMapper.class, MediaType.WILDCARD_TYPE);
ObjectMapper mapper = resolver.getContext(ObjectMapper.class);

If you are interested in getting @XxxParam names, refer to this answer.


No, that's not possible. Hibernate Validator 5 (Bean Validation 1.1) has the notion of ParameterNameProviders which return the names to reported in case method parameter constraints are violated but there is nothing comparable for property constraints.