<table role="table">
<thead>
<tr>
<th>Q</th>
<th>A</th>
</tr>
</thead>
<tbody>
<tr>
<td>Bug report?</td>
<td>maybe</td>
</tr>
<tr>
<td>Feature request?</td>
<td>yes/no</td>
</tr>
<tr>
<td>BC Break report?</td>
<td>no</td>
</tr>
<tr>
<td>RFC?</td>
<td>no</td>
</tr>
<tr>
<td>Symfony version</td>
<td>3.3.8</td>
</tr>
</tbody>
</table>
<p dir="auto">I have an issue with validator component. I have a base class and a child. Base class defines a property and a set of constaints. Child must redefine one of the constraints - it must modify its options.I am using StaticMethodLoader for both classes because I am in control and I can work with constraints. The problem is that I get two violations instead of one when validating child object. Constraint is validated twice - with child options first and then with base class options. I tried to investigate why but I still don't know why its happening. And I am a bit lost in all the loaders and caching.</p>
<p dir="auto">However, the result is quite unexpected for me. I thought that validator honors inheritance.</p>
<p dir="auto">Thanks for any help.</p>
<p dir="auto">A simple example—</p>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Validation;
use Doctrine\Common\Annotations\AnnotationRegistry;

AnnotationRegistry::registerAutoloadNamespace('Symfony\Component\Validator\Constraints', __DIR__);

class Parent
{
    /**
     * @Assert\EqualTo(0)
     */
    public $example = 0;
}

class Child extends Parent
{
    /**
     * @Assert\EqualTo(1)
     */
    public $example = 1;    // overrides parent property of same name
}

echo Validation::createValidatorBuilder()
               -&gt;enableAnnotationMapping()
               -&gt;getValidator()
               -&gt;validate(new Child());"><pre class="notranslate"><span class="pl-k">use</span> <span class="pl-v">Symfony</span>\<span class="pl-v">Component</span>\<span class="pl-v">Validator</span>\<span class="pl-v">Constraints</span> <span class="pl-k">as</span> <span class="pl-v">Assert</span>;
<span class="pl-k">use</span> <span class="pl-v">Symfony</span>\<span class="pl-v">Component</span>\<span class="pl-v">Validator</span>\<span class="pl-v">Validation</span>;
<span class="pl-k">use</span> <span class="pl-v">Doctrine</span>\<span class="pl-v">Common</span>\<span class="pl-v">Annotations</span>\<span class="pl-v">AnnotationRegistry</span>;

<span class="pl-v">AnnotationRegistry</span>::<span class="pl-en">registerAutoloadNamespace</span>(<span class="pl-s">'Symfony\Component\Validator\Constraints'</span>, __DIR__);

<span class="pl-k">class</span> <span class="pl-v">Parent</span>
{
    <span class="pl-c">/**</span>
<span class="pl-c">     * @Assert\EqualTo(0)</span>
<span class="pl-c">     */</span>
    <span class="pl-k">public</span> <span class="pl-c1"><span class="pl-c1">$</span>example</span> = <span class="pl-c1">0</span>;
}

<span class="pl-k">class</span> <span class="pl-v">Child</span> <span class="pl-k">extends</span> <span class="pl-v">Parent</span>
{
    <span class="pl-c">/**</span>
<span class="pl-c">     * @Assert\EqualTo(1)</span>
<span class="pl-c">     */</span>
    <span class="pl-k">public</span> <span class="pl-c1"><span class="pl-c1">$</span>example</span> = <span class="pl-c1">1</span>;    <span class="pl-c">// overrides parent property of same name</span>
}

<span class="pl-k">echo</span> <span class="pl-v">Validation</span>::<span class="pl-en">createValidatorBuilder</span>()
               -&gt;<span class="pl-en">enableAnnotationMapping</span>()
               -&gt;<span class="pl-en">getValidator</span>()
               -&gt;<span class="pl-en">validate</span>(<span class="pl-k">new</span> <span class="pl-v">Child</span>());</pre></div>
<p dir="auto">The validation fails because the constraint that was defined on <code class="notranslate">Parent::$example</code> has been merged with that for <code class="notranslate">Child::$example</code> (and, in this case, they are mutually exclusive).</p>
<p dir="auto">This cannot be right—the child property has completely replaced that of the parent and all of the latter's metadata (including validation constraints) should be discarded.</p>
<p dir="auto">For the time being, I have added the following two lines after <a href="https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php#L61"><code class="notranslate">AnnotationLoader.php:61</code></a>:</p>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="                unset($metadata-&gt;members[$property-&gt;name]);
                unset($metadata-&gt;properties[$property-&gt;name]);"><pre class="notranslate">                unset(<span class="pl-s1"><span class="pl-c1">$</span>metadata</span>-&gt;<span class="pl-c1">members</span>[<span class="pl-s1"><span class="pl-c1">$</span>property</span>-&gt;<span class="pl-c1">name</span>]);
                unset(<span class="pl-s1"><span class="pl-c1">$</span>metadata</span>-&gt;<span class="pl-c1">properties</span>[<span class="pl-s1"><span class="pl-c1">$</span>property</span>-&gt;<span class="pl-c1">name</span>]);</pre></div>
<p dir="auto">However, I acknowledge that this is horrible—at very least, <code class="notranslate">ClassMetadata</code> should provide a method for resetting a property, but even if one could use that I'm not familiar enough with the code to be certain that this approach doesn't break something else.  Grateful for your thoughts!</p>