We're updating the issue view to help you get more done. 

Make the “propertyPath” available via the “HibernateMessageInterpolatorContext”

Description

We use bean validation intensively for validation of incoming SOAP messages. These SOAP messages contain an (hierarchical) object graph (no backlinks), consisting out of entities (beans) and attributes (bean-properties).
Our failure messages are standardized. They typically start with the failing constraint property and refer to other relevant properties. We have written many custom validators for our domain.

For example, the following ValidationMessages.properties entry describes such a message, called by a custom nl.bro.dto.common.validation.AssertEmpty validator.

ValidationMessages.properties

1 nl.bro.dto.common.validation.AssertEmpty.message=${validatedAttribute} is missing: ${refAttribute} = ${indicationYesNoValue} determines that it must be present.

Now, all el-expressions value expressions are populated are resolved via the custom AssertEmpty, Constraint annotated annotation. Their values are asserted by the custom AssertEmptyValidator.

The intention is that ${validatedAttribute} and ${refAttribute} are replaced by a parameter. The parameter reflects their position in the object graph and is used in the ValidationMessages.properties resource bundle as key to find the proper name.

So, suppose that we evaluate an object:

Car.java

1 2 3 4 Car { String hornPresent; Steer steer; }

Steer.java

1 2 3 Steer { Horn horn; }

To achieve this we have written one custom message interpolator. This interpolates the message to:

Intermediate Interpolation Result

1 nl.bro.dto.common.validation.AssertEmpty.message={Car.steer.horn} is missing: {Car.hornPresent} = ${indicationYesNoValue} determines that it must be present.

However, we can’t fully solve this directly in a custom message interpolator. For this we require the rootBean and the propertyPath. Both are present on the ConstraintViolation but not on the MessageInterpolator.Context. The rootBeanType however can be resolved via unwrapping to the HibernateMessageInterpolatorContext but the propertyPath can’t.

The current solution entails:

  1. Having a custom message interpolator, storing the ConstraintDescriptor as key and the HibernateMessageInterpolatorContext as value in a ThreadLocal.

  1. We wrap all relevant HV classes (ValidatorFactory, Validator, ConstraintViolation) to get to the propertyPath and apply post-interpolation on the violation message by using the ConstraintDescriptor in the ConstraintViolation to get the MessageInterpolator.Context belonging to that particular ConstraintViolation. No need to say this is cumbersome and could be far more simple if we have the proper information available in the custom message interpolator.

NB: I can see that in the interpolation the ConstraintViolation is created almost at the same point as the MessageInterpolator.Context.

Environment

JBOSS7, Java8

Status

Assignee

Sjaak Derksen

Reporter

Sjaak Derksen

Labels

None

Worked in

None

Feedback Requested

None

Feedback Requested By

None

backPortable

None

Community Help Wanted

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

backportReEvaluate

None

Components

Fix versions

Affects versions

6.0.13.Final
5.4.3.Final

Priority

Major