<table role="table">
<thead>
<tr>
<th>Q</th>
<th>A</th>
</tr>
</thead>
<tbody>
<tr>
<td>Bug report?</td>
<td>yes</td>
</tr>
<tr>
<td>Feature request?</td>
<td>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>&gt;=3.2.2 &gt;=3.3.0-beta1</td>
</tr>
</tbody>
</table>
<p dir="auto">Validation caching merges constraints for class and all of its parents. It's wrong behaviour, because the class already contains constraints from parent classes. As a result we have duplicated constraint.</p>
<h3 dir="auto">The way to reproduce</h3>
<p dir="auto">Create two models, the second one extends the first one:</p>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="namespace AppBundle\Model;

class Foo
{
    public $foo;
}"><pre class="notranslate"><span class="pl-k">namespace</span> <span class="pl-v">AppBundle</span>\<span class="pl-v">Model</span>;

<span class="pl-k">class</span> <span class="pl-v">Foo</span>
{
    <span class="pl-k">public</span> <span class="pl-c1"><span class="pl-c1">$</span>foo</span>;
}</pre></div>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="namespace AppBundle\Model;

class Bar extends Foo
{
}"><pre class="notranslate"><span class="pl-k">namespace</span> <span class="pl-v">AppBundle</span>\<span class="pl-v">Model</span>;

<span class="pl-k">class</span> <span class="pl-v">Bar</span> <span class="pl-k">extends</span> <span class="pl-v">Foo</span>
{
}</pre></div>
<p dir="auto">Create validation config, add constraint to the first class, the second class should be defined (empty or with some constraints)</p>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="AppBundle\Model\Foo:
    constraints:
        - Expression: &quot;this.foo !== null&quot;

AppBundle\Model\Bar:"><pre class="notranslate"><span class="pl-ent">AppBundle\Model\Foo</span>:
    <span class="pl-ent">constraints</span>:
        - <span class="pl-ent">Expression</span>: <span class="pl-s"><span class="pl-pds">"</span>this.foo !== null<span class="pl-pds">"</span></span>

<span class="pl-ent">AppBundle\Model\Bar</span>:</pre></div>
<p dir="auto">And validation of new <code class="notranslate">Bar</code> object will generates two duplicated violations:</p>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="$container-&gt;get('validator')-&gt;validate(new Bar()));"><pre class="notranslate"><span class="pl-s1"><span class="pl-c1">$</span>container</span>-&gt;<span class="pl-en">get</span>(<span class="pl-s">'validator'</span>)-&gt;<span class="pl-en">validate</span>(<span class="pl-k">new</span> <span class="pl-v">Bar</span>()));</pre></div>
<p dir="auto">Note: this code should be executed in prod environment, because test environment doesn't use validation cache by default.</p>
<p dir="auto">Drupal needs potentially to adapt the exception listener to add more information from the original request. (see <a href="http://drupal.org/node/2057607" rel="nofollow">http://drupal.org/node/2057607</a>) so what about extracing some of the logic into a new method.</p>
<table role="table">
<thead>
<tr>
<th>Q</th>
<th>A</th>
</tr>
</thead>
<tbody>
<tr>
<td>Bug fix?</td>
<td>no</td>
</tr>
<tr>
<td>New feature?</td>
<td>yes</td>
</tr>
<tr>
<td>BC breaks?</td>
<td>no</td>
</tr>
<tr>
<td>Deprecations?</td>
<td>no</td>
</tr>
<tr>
<td>Tests pass?</td>
<td>yes</td>
</tr>
<tr>
<td>Fixed tickets</td>
<td></td>
</tr>
<tr>
<td>License</td>
<td>MIT</td>
</tr>
</tbody>
</table>