<p dir="auto">After i integrated <code class="notranslate">console.command</code> tags into Shopware <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="156152216" data-permission-text="Title is private" data-url="https://github.com/shopware5/shopware/issues/559" data-hovercard-type="pull_request" data-hovercard-url="/shopware5/shopware/pull/559/hovercard" href="https://github.com/shopware5/shopware/pull/559">shopware5/shopware#559</a> we hade a discussion about <code class="notranslate">Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConsoleCommandPass</code> and its FrameworkBundle dependency.</p>
<p dir="auto">A project with <code class="notranslate">symfony/console</code> and <code class="notranslate">symfony/dependency-injection</code> need to copy this CompilerPass. <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/bcremer/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/bcremer">@bcremer</a> and <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/xabbuh/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/xabbuh">@xabbuh</a> had some ideas to move this class.</p>
<p dir="auto">Maybe we can optimize command registration over dic somehow.</p>
<p dir="auto">Symfony: 2.5.9<br>
Doctrine ORM:  2.4.6<br>
Doctrine bundle:  1.2</p>
<p dir="auto">Hello -</p>
<p dir="auto">I have come across a strange issue with processing form collections in Symfony.</p>
<p dir="auto">I have a User entity that has a collection of List Items associated with it.  Each List Item entity also references another entity, Topic.  I have setup a UNIQUE constraint on the List Item table that will only allow unique combinations of the User and Topic foreign keys.  Essentially - no List Items with a duplicate reference to the Topic entity are allowed for each user.</p>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/**
 * @ORM\Entity(repositoryClass=&quot;App\MyBundle\Repository\ListItemRepository&quot;)
 * @ORM\Table(
 *     name=&quot;list_items&quot;,
 *     uniqueConstraints={@ORM\UniqueConstraint(name=&quot;list_item_user_topic&quot;, columns={&quot;user_id&quot;,&quot;topic_id&quot;})}
 * )
 *
 * @Gedmo\SoftDeleteable(fieldName=&quot;deleted_at&quot;, timeAware=true)
 */
class ListItem
{
..."><pre class="notranslate"><span class="pl-c">/**</span>
<span class="pl-c"> * @ORM\Entity(repositoryClass="App\MyBundle\Repository\ListItemRepository")</span>
<span class="pl-c"> * @ORM\Table(</span>
<span class="pl-c"> *     name="list_items",</span>
<span class="pl-c"> *     uniqueConstraints={@ORM\UniqueConstraint(name="list_item_user_topic", columns={"user_id","topic_id"})}</span>
<span class="pl-c"> * )</span>
<span class="pl-c"> *</span>
<span class="pl-c"> * @Gedmo\SoftDeleteable(fieldName="deleted_at", timeAware=true)</span>
<span class="pl-c"> */</span>
<span class="pl-k">class</span> <span class="pl-v">ListItem</span>
{
...</pre></div>
<p dir="auto">I am using Symfony form builder to build the form.  This is working great.  I have added javascript for add/remove buttons on the frontend.  In general - I am able to save and persist the form collection without any problems.</p>
<p dir="auto">However - there are time when I will be attempting to persist the User entity and the List Item form collection and it will fail with an integrity constraint violation.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '6-1' for key 'list_item_user_topic'"><pre class="notranslate"><code class="notranslate">SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '6-1' for key 'list_item_user_topic'
</code></pre></div>
<p dir="auto">This was initially very strange to me because I also have an event listener that is listening to the Doctrine "onFlush" event that does the following:</p>
<ol dir="auto">
<li>Check if the entity is a List Item</li>
<li>If it is a List Item, it checks the database for an existing record for that user</li>
<li>Since I am using SoftDeletes - if the record exists and it's been soft deleted - it will un-delete the record and replace the new duplicate record with it - maintaining the record in the database.</li>
<li>If a duplicate record that is published is found - it will simply remove the new duplicate record from the scheduled inserts and keep the one in the database.</li>
</ol>
<p dir="auto">This is all happening onFlush - which occurs AFTER handleRequest.  What I discovered is that when the form is being processed - something is happening within the handleRequest() method that is swapping out foreign key references on different rows.  Like so:</p>
<p dir="auto">Original Item List for a user:</p>
<table role="table">
<tbody><tr><td>ID</td><td>user_id</td><td>topic_id</td><td>info</td></tr>
<tr><td>1</td><td>10</td><td>57</td><td>extra info</td></tr>
<tr><td>2</td><td>10</td><td>83</td><td>extra info</td></tr>
<tr><td>3</td><td>10</td><td>233</td><td>extra info</td></tr>
</tbody></table>
<p dir="auto">After form passes through the handleRequest() method:</p>
<table role="table">
<tbody><tr><td>ID</td><td>user_id</td><td>topic_id</td><td>info</td></tr>
<tr><td>1</td><td>10</td><td>233</td><td>extra info</td></tr>
<tr><td>2</td><td>10</td><td>83</td><td>extra info</td></tr>
<tr><td>3</td><td>10</td><td>57</td><td>extra info</td></tr>
</tbody></table>
<p dir="auto">This then causes the integrity constraint violation when it attempts to write the first record because it is violating the unique constraint on the List Items table.  What I do not understand is how/why the handleRequest() method would be swapping foreign keys on update.</p>
<p dir="auto">The other really strange thing is that in many cases - the form will persist fine for a user.  I hate to use the word "random" here but I have not been able to identify a way to duplicate the issue other than just working with the entity for a while and performing CRUD operations on it.  Many times the form persists fine - other times the foreign key references get swapped and I am unable to submit the form to update the entity because of the UNIQUE constraint.</p>
<p dir="auto">Has anyone experienced similar issues or have some insight on why this might be occurring?  Is this a bug in the handleRequest() method?  This will occur even if I have not made any changes to the List Item collection.  As in - if I edit a user and simply submit the form without making any changes - this behavior will still occur.</p>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="    public function editAction($id, Request $request)
    {
        // Get entity manager
        $em = $this-&gt;getDoctrine()-&gt;getManager();

        // Fetch data to populate form
        $user = $this
            -&gt;get('user_repository')
            -&gt;fetchProfileById($id)
            -&gt;getQuery()
            -&gt;getSingleResult();

        // Build form
        $form = $this-&gt;createForm('user', $user);

        // Handle request
        $form-&gt;handleRequest($request);

        // Form validation
        if ($form-&gt;isValid())
        {
            try
            {
                $em-&gt;flush();

                $message = 'User updated successfully!';

                // Return successful message
                $this-&gt;get('session')
                    -&gt;getFlashBag()
                    -&gt;add('success', $message);
            }
            catch (Exception $e)
            {
                $message = 'There was an error updating the user.' . $e-&gt;getMessage();

                // Return error message
                $this-&gt;get('session')
                    -&gt;getFlashBag()
                    -&gt;add('error', $message);
            }

            // Return view
            return new RedirectResponse($this-&gt;generateUrl('users_list'));
        }
}"><pre class="notranslate">    <span class="pl-k">public</span> <span class="pl-k">function</span> <span class="pl-en">editAction</span>(<span class="pl-s1"><span class="pl-c1">$</span>id</span>, <span class="pl-smi"><span class="pl-smi">Request</span></span> <span class="pl-s1"><span class="pl-c1">$</span>request</span>)
    {
        <span class="pl-c">// Get entity manager</span>
        <span class="pl-s1"><span class="pl-c1">$</span>em</span> = <span class="pl-s1"><span class="pl-c1">$</span><span class="pl-smi">this</span></span>-&gt;<span class="pl-en">getDoctrine</span>()-&gt;<span class="pl-en">getManager</span>();

        <span class="pl-c">// Fetch data to populate form</span>
        <span class="pl-s1"><span class="pl-c1">$</span>user</span> = <span class="pl-s1"><span class="pl-c1">$</span><span class="pl-smi">this</span></span>
            -&gt;<span class="pl-en">get</span>(<span class="pl-s">'user_repository'</span>)
            -&gt;<span class="pl-en">fetchProfileById</span>(<span class="pl-s1"><span class="pl-c1">$</span>id</span>)
            -&gt;<span class="pl-en">getQuery</span>()
            -&gt;<span class="pl-en">getSingleResult</span>();

        <span class="pl-c">// Build form</span>
        <span class="pl-s1"><span class="pl-c1">$</span>form</span> = <span class="pl-s1"><span class="pl-c1">$</span><span class="pl-smi">this</span></span>-&gt;<span class="pl-en">createForm</span>(<span class="pl-s">'user'</span>, <span class="pl-s1"><span class="pl-c1">$</span>user</span>);

        <span class="pl-c">// Handle request</span>
        <span class="pl-s1"><span class="pl-c1">$</span>form</span>-&gt;<span class="pl-en">handleRequest</span>(<span class="pl-s1"><span class="pl-c1">$</span>request</span>);

        <span class="pl-c">// Form validation</span>
        <span class="pl-k">if</span> (<span class="pl-s1"><span class="pl-c1">$</span>form</span>-&gt;<span class="pl-en">isValid</span>())
        {
            <span class="pl-k">try</span>
            {
                <span class="pl-s1"><span class="pl-c1">$</span>em</span>-&gt;<span class="pl-en">flush</span>();

                <span class="pl-s1"><span class="pl-c1">$</span>message</span> = <span class="pl-s">'User updated successfully!'</span>;

                <span class="pl-c">// Return successful message</span>
                <span class="pl-s1"><span class="pl-c1">$</span><span class="pl-smi">this</span></span>-&gt;<span class="pl-en">get</span>(<span class="pl-s">'session'</span>)
                    -&gt;<span class="pl-en">getFlashBag</span>()
                    -&gt;<span class="pl-en">add</span>(<span class="pl-s">'success'</span>, <span class="pl-s1"><span class="pl-c1">$</span>message</span>);
            }
            <span class="pl-k">catch</span> (<span class="pl-smi"><span class="pl-smi">Exception</span></span> <span class="pl-s1"><span class="pl-c1">$</span>e</span>)
            {
                <span class="pl-s1"><span class="pl-c1">$</span>message</span> = <span class="pl-s">'There was an error updating the user.'</span> . <span class="pl-s1"><span class="pl-c1">$</span>e</span>-&gt;<span class="pl-en">getMessage</span>();

                <span class="pl-c">// Return error message</span>
                <span class="pl-s1"><span class="pl-c1">$</span><span class="pl-smi">this</span></span>-&gt;<span class="pl-en">get</span>(<span class="pl-s">'session'</span>)
                    -&gt;<span class="pl-en">getFlashBag</span>()
                    -&gt;<span class="pl-en">add</span>(<span class="pl-s">'error'</span>, <span class="pl-s1"><span class="pl-c1">$</span>message</span>);
            }

            <span class="pl-c">// Return view</span>
            <span class="pl-k">return</span> <span class="pl-k">new</span> <span class="pl-v">RedirectResponse</span>(<span class="pl-s1"><span class="pl-c1">$</span><span class="pl-smi">this</span></span>-&gt;<span class="pl-en">generateUrl</span>(<span class="pl-s">'users_list'</span>));
        }
}</pre></div>