<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Olivier Lechevalier</title>
    <description>The latest articles on DEV Community by Olivier Lechevalier (@ragezbla).</description>
    <link>https://dev.to/ragezbla</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F131405%2F181a8fd7-c71c-4e74-a4a3-1a7f00fcbdd7.png</url>
      <title>DEV Community: Olivier Lechevalier</title>
      <link>https://dev.to/ragezbla</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ragezbla"/>
    <language>en</language>
    <item>
      <title>BDD working together with Hexagonal architecture</title>
      <dc:creator>Olivier Lechevalier</dc:creator>
      <pubDate>Sun, 25 Aug 2019 00:02:36 +0000</pubDate>
      <link>https://dev.to/ragezbla/bdd-working-together-with-hexagonal-architecture-2on9</link>
      <guid>https://dev.to/ragezbla/bdd-working-together-with-hexagonal-architecture-2on9</guid>
      <description>&lt;p&gt;Behaviour driven development is a development methodology that aims to create a good communication between the development team and the business. It also focus the testing on the actual behaviour of the system rather than focusing too much on low level details. &lt;/p&gt;

&lt;p&gt;Sadly over the years cucumber (and behat) was used as an user acceptance testing tool or solely to write end to end tools. The creator of cucumber actually made a blog &lt;a href="https://aslakhellesoy.com/post/11055981222/the-training-wheels-came-off" rel="noopener noreferrer"&gt;post&lt;/a&gt; titled "The training wheels came off" trying to explain why using cucumber as a web test automation was just a bad idea. He made a point that by doing so you would not reap any of the benefits that BDD should provide you. &lt;/p&gt;

&lt;p&gt;Now let's hope you are not writing anymore scenarios like this one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gherkin"&gt;&lt;code&gt;&lt;span class="kn"&gt;Scenario&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; Successful login
  &lt;span class="nf"&gt;Given &lt;/span&gt;a user &lt;span class="s"&gt;"Aslak"&lt;/span&gt; with password &lt;span class="s"&gt;"xyz"&lt;/span&gt;
  &lt;span class="nf"&gt;And &lt;/span&gt;I am on the login page
  &lt;span class="nf"&gt;And &lt;/span&gt;I fill in &lt;span class="s"&gt;"User name"&lt;/span&gt; with &lt;span class="s"&gt;"Aslak"&lt;/span&gt;
  &lt;span class="nf"&gt;And &lt;/span&gt;I fill in &lt;span class="s"&gt;"Password"&lt;/span&gt; with &lt;span class="s"&gt;"xyz"&lt;/span&gt;
  &lt;span class="nf"&gt;When &lt;/span&gt;I press &lt;span class="s"&gt;"Log in"&lt;/span&gt;
  &lt;span class="nf"&gt;Then &lt;/span&gt;I should see &lt;span class="s"&gt;"Welcome, Aslak"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Moving on to hexagonal architecture, A.K.A. ports and adapters. This architecture was coined by a gentleman named Alistair Cockburn in June 2005. It aims to write highly testable applications. It does so by providing clean layers and pushing all the technical bits to "adapters". The application core has to provide contracts (interfaces) "ports" that the infrastructure layers should implement (adapters).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fspeakerd.s3.amazonaws.com%2Fpresentations%2Fde8629f0bf520131c2e20239d959ba18%2Fslide_11.jpg%3F1400675141" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fspeakerd.s3.amazonaws.com%2Fpresentations%2Fde8629f0bf520131c2e20239d959ba18%2Fslide_11.jpg%3F1400675141" alt="the hexagon"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In case you want to read more into the subject, I highly recommend Chris Fidao (fideloper) &lt;a href="https://fideloper.com/hexagonal-architecture" rel="noopener noreferrer"&gt;post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now what these two things can do for us. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3o7TKHKjrDyqphX9Cg/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3o7TKHKjrDyqphX9Cg/giphy.gif" alt="shrug"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Basically usually if use BDD tool but you are testing using the UI of your application (web testing, end to end), it means there is a big chance that these tests are slow and flaky. On the other hand, if you follow the hexagonal architecture motto: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Allow an application to equally be driven by users, programs, automated test or batch scripts, and to be developed and tested in isolation from its eventual run-time devices and databases.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It means that your should be able to write tests that bypass your web interface and go talk directly to the application layer. This bring two major benefits.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;you can't write scenarios that are too focused on the UI (there is no more UI involved)&lt;/li&gt;
&lt;li&gt;it will be super fast!!!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Just to prove my point here the output from a real application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;93 scenarios (93 passed)
384 steps (384 passed)
0m5.31s (58.20Mb)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://i.giphy.com/media/V0IdVIIW1y5d6/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/V0IdVIIW1y5d6/giphy.gif" alt="mind blow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enjoy clean testable applications with up-to-date documentation written in Gherkin. &lt;/p&gt;

&lt;p&gt;Bonus: these scenarios could be maintained by business analysis or domain expert.&lt;/p&gt;

</description>
      <category>hexagonal</category>
      <category>bdd</category>
      <category>testing</category>
    </item>
    <item>
      <title>Doctrine: HOW TO recover from rolled back transaction</title>
      <dc:creator>Olivier Lechevalier</dc:creator>
      <pubDate>Sun, 21 Jul 2019 09:40:18 +0000</pubDate>
      <link>https://dev.to/ragezbla/doctrine-how-to-recover-from-rolled-back-transaction-47o4</link>
      <guid>https://dev.to/ragezbla/doctrine-how-to-recover-from-rolled-back-transaction-47o4</guid>
      <description>&lt;p&gt;We all wish we would have to deal only with the happy paths, sadly in reality errors happen and we have to handle them. &lt;/p&gt;

&lt;p&gt;One way to clean the mess after an error happened is database transactions and particularly rollbacks. Transaction is a powerful tool to prevent our application to leave the database in an unknown or broken state. &lt;/p&gt;

&lt;p&gt;Sadly most of ORMs are not really well equipped to deal with rollbacks. &lt;/p&gt;

&lt;p&gt;Let's take a look at a small real world example. Our application needs to send some email to customers and record that the email was sent. The processing is done in batch by doing the action on one customer at a time.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;


&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;sendWeeklyNewsletter&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$customers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$repository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$customers&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$entityManager&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;transactional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;sendWeeklyNewsletter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$customer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;recordEmailNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$customer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;EmailNotTransmittedException&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let's say the first email could not be sent (random outages, incorrect email, etc), you would think it should work, &lt;code&gt;transactional&lt;/code&gt; would rollback the transaction and it would continue processing the next customer.&lt;/p&gt;

&lt;p&gt;Unfortunately, it's not the case, you would be rewarded with this exception &lt;code&gt;PHP Fatal error:  Uncaught Doctrine\ORM\ORMException: The EntityManager is closed.&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Taking a look at the code of &lt;code&gt;EntityManager::transactional&lt;/code&gt; would explain why.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;

    &lt;span class="cd"&gt;/**
     * {@inheritDoc}
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;transactional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;is_callable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$func&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\InvalidArgumentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Expected argument of type "callable", got "'&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nb"&gt;gettype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'"'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;beginTransaction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$return&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;call_user_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$func&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;flush&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$return&lt;/span&gt; &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Throwable&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;rollBack&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Basically because dealing with rollback is complicated. The doctrine maintainers choose to close the entity manager as soon a rollback happens. The &lt;a href="https://www.doctrine-project.org/projects/doctrine-orm/en/current/reference/transactions-and-concurrency.html#exception-handling" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; includes such warning:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As a result of this procedure, all previously managed or removed instances of the EntityManager become detached. The state of the detached objects will be the state at the point at which the transaction was rolled back. The state of the objects is in no way rolled back and thus the objects are now out of synch with the database. The application can continue to use the detached objects, knowing that their state is potentially no longer accurate.&lt;br&gt;
&lt;strong&gt;If you intend to start another unit of work after an exception has occurred you should do that with a new EntityManager.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;TD;LR you can't use an entity manager after a rollback happened.&lt;/p&gt;

&lt;p&gt;Now how do we do our batch processing if we can't recover from errors!?!?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F63ixguxnwmwfp6f4f31z.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F63ixguxnwmwfp6f4f31z.gif" alt="oh dear jesus"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need to create a new entity manager every time a rollback happens. This could get complicated if you are using a container because it would share the same instance of entity manager everywhere.&lt;/p&gt;

&lt;p&gt;Behold the &lt;code&gt;AbstractManagerRegistry&lt;/code&gt;, this registry has a &lt;code&gt;resetManager&lt;/code&gt; method that allow to create a new entity manager.&lt;/p&gt;

&lt;p&gt;Anyway if you are using symfony framework, the doctrine bridge bundle provides an implementation of the doctrine registry and allow you to reset the entity manager. I am pretty sure other frameworks integration should provide the same feature.&lt;/p&gt;

&lt;p&gt;So our code becomes:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;


&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;sendWeeklyNewsletter&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$customers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$repository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$customers&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$entityManager&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;transactional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;sendWeeklyNewsletter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$customer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;recordEmailNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$customer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;EmailNotTransmittedException&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;resetManager&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The attentive reader might have caught a problem in our logic. The entity manager was already passed to our class so it can't be swapped. In fact the symfony doctrine bundle rely on the wonderful &lt;a href="https://github.com/Ocramius/ProxyManager" rel="noopener noreferrer"&gt;proxy manager&lt;/a&gt; library written by Ocramius to wrap the EntityManager object so it can be swapped dynamically.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgdvoovussjewdz1i5ib3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgdvoovussjewdz1i5ib3.gif" alt="smart"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anyway you can take a look at the &lt;a href="https://github.com/symfony/doctrine-bridge/blob/master/ManagerRegistry.php#L41" rel="noopener noreferrer"&gt;implementation&lt;/a&gt; of the registry.&lt;/p&gt;

&lt;p&gt;Happy batch processing!&lt;/p&gt;

</description>
      <category>php</category>
      <category>doctrine</category>
      <category>orm</category>
      <category>symfony</category>
    </item>
  </channel>
</rss>
