<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Property names passed to<div>context.addError(message, "myProperty");</div><div>used to be limited to existing properties and could only be used if the constraint declaration was on the class-level.</div><div>Otherwise, an exception was raised.</div><div><br></div><div>I relaxed this rule as some people came with use cases involving validating property values by navigating properties hosted on the property value.</div><div><br></div><div>@SafeZipCodeAndCity</div><div>public Address getAddress() { ... }</div><div><br></div><div>Here is the new wording</div><div><br></div><div><span class="Apple-style-span" style="font-family: -webkit-sans-serif; font-size: 14px; "><div class="example" style="font-family: sans-serif; font-size: 14px; "><p class="title" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); margin-top: 10px; padding-top: 5px; font-weight: bold; "><span class="Apple-style-span" style="font-weight: normal; "><div class="example" style="font-family: sans-serif; font-size: 14px; "><p class="title" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); margin-top: 10px; padding-top: 5px; font-weight: bold; "><b style="font-family: sans-serif; font-size: 14px; ">Example&nbsp;2.13.&nbsp;ConstraintValidatorContext interface passed to ConstraintValidator.isValid()</b></p><pre class="programlisting" style="font-size: 100%; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: rgb(204, 204, 204); border-right-color: rgb(204, 204, 204); border-bottom-color: rgb(204, 204, 204); border-left-color: rgb(204, 204, 204); background-color: rgb(244, 244, 244); font-family: monospace; width: auto; ">/**
 * Provide contextual data and operation when applying a given constraint validator implementation
 *
 * @author Emmanuel Bernard
 */
public interface ConstraintValidatorContext {
        /**
         * Disable default error message and default ConstraintViolation object generation.
         * Useful to set a different error message or generate an ConstraintViolation based on
         * a different property
         *
         * @see #addError(String)
         * @see #addError(String, String)
         */
        void disableDefaultError();

        /**
         * @return the current unexpanded default message
         */
        String getDefaultErrorMessage();

        /**
         * Add a new error message. This error message will be interpolated.
         * &lt;p/>
         * If isValid returns false, a ConstraintViolation object will be built per error message
         * including the default one unless #disableDefaultError() has been called.
         * &lt;p/>
         * Aside from the error message, ConstraintViolation objects generated from such a call
         * contains the same contextual information (root bean, path and so on)
         * &lt;p/>
         * This method can be called multiple time. One ConstraintViolation instance per
         * call is created.
         *
         * @param message new unexpanded error message
         */
        void addError(String message);

        /**
         * Add a new error message to a given sub property &lt;code>property&lt;/code>.
         * This error message will be interpolated.
         * &lt;p/>
         * If isValid returns false, a ConstraintViolation object will be built
         * per error message including the default one unless #disableDefaultError()
         * has been called.
         * &lt;p/>
         *
         * @param message new unexpanded error message
         * @param property property name the ConstraintViolation is targeting
         */
        void addError(String message, String property);
}</pre></div></span></p><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">The&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidatorContext</tt>&nbsp;interface allows to redefine the default message error generated when a constraint is not valid. By default, each invalid constraint leads to the generation of one error object represented by a&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintViolation</tt>&nbsp;object. This object is build from the default error message as defined by the constraint declaration and the context in which the constraint declaration is placed on (bean, property, attribute).</p><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">The&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidatorContext</tt>&nbsp;methods let the constraint implementation disable the default error object generation and create one or more custom ones. The unexpanded message passed as a parameter is used to build the&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintViolation</tt>&nbsp;object (the message interpolation operation is applied to it). The property on which the error object is applied is defined as following:</p><div class="itemizedlist" style="font-family: sans-serif; font-size: 14px; "><ul type="disc" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><li style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">if property is not overridden, the current context the constraint is declared on is used (bean or property)</p></li><li style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">if the property is overridden, the current context the constraint is declared on the property passed as a parameter relative to the constraint declaration being evaluated</p></li></ul></div><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">The property can be overridden by calling&nbsp;<tt class="methodname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidatorContext.addError(String, String)</tt>.</p></div></span></div></div></body></html>