title: Symfony2 form validation exhausted memory
body: <p>I have a complex form with many entity choice field. When I don't use validation, add/edit is okay. But when I enable form validation in /config/validation.yml, I can't add/edit anymore.
  I checked php log files and see some error:</p>
  
  <pre><code>PHP Fatal error:  Allowed memory size of 536870912 bytes exhausted (tried to allocate 32 bytes) in ..\example.com\vendor\doctrine\dbal\lib\Doctrine\DBAL\Connection.php on line 694
  PHP Stack trace:
  PHP   1. {main}() ..\example.com\web\app_dev.php:0
  PHP   2. Symfony\Component\HttpKernel\Kernel-&gt;handle() ..\example.com\web\app_dev.php:29
  PHP   3. Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel-&gt;handle() ..\example.com\var\bootstrap.php.cache:2377
  PHP   4. Symfony\Component\HttpKernel\HttpKernel-&gt;handle() ..\example.com\var\bootstrap.php.cache:3133
  PHP   5. Symfony\Component\HttpKernel\HttpKernel-&gt;handleRaw() ..\example.com\var\bootstrap.php.cache:2984
  PHP   6. call_user_func_array:{..\example.com\var\bootstrap.php.cache:3022}() ..\example.com\var\bootstrap.php.cache:3022
  PHP   7. DefaultBundle\Controller\PropertyHouseController-&gt;createAction() ..\example.com\var\bootstrap.php.cache:3022
  PHP   8. Symfony\Component\Form\Form-&gt;createView() ..\example.com\src\DefaultBundle\Controller\PropertyHouseController.php:86
  PHP   9. Symfony\Component\Form\Form-&gt;createView() ..\example.com\vendor\symfony\symfony\src\Symfony\Component\Form\Form.php:1061
  PHP  10. Symfony\Component\Form\Extension\DataCollector\Proxy\ResolvedTypeDataCollectorProxy-&gt;buildView() ..\example.com\vendor\symfony\symfony\src\Symfony\Component\Form\Form.php:1058
  PHP  11. Symfony\Component\Form\ResolvedFormType-&gt;buildView() ..\example.com\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\DataCollector\Proxy\ResolvedTypeDataCollectorProxy.php:111
  PHP  12. Symfony\Component\Form\Extension\DataCollector\Proxy\ResolvedTypeDataCollectorProxy-&gt;buildView() ..\example.com\vendor\symfony\symfony\src\Symfony\Component\Form\ResolvedFormType.php:159
  PHP  13. Symfony\Component\Form\ResolvedFormType-&gt;buildView() ..\example.com\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\DataCollector\Proxy\ResolvedTypeDataCollectorProxy.php:111
  PHP  14. Symfony\Component\Form\Extension\Core\Type\ChoiceType-&gt;buildView() ..\example.com\vendor\symfony\symfony\src\Symfony\Component\Form\ResolvedFormType.php:162
  PHP  15. Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList-&gt;getPreferredViews() ..\example.com\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\Core\Type\ChoiceType.php:101
  PHP  16. Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList-&gt;load() ..\example.com\vendor\symfony\symfony\src\Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList.php:174
  PHP  17. Symfony\Bridge\Doctrine\Form\ChoiceList\ORMQueryBuilderLoader-&gt;getEntities() ..\example.com\vendor\symfony\symfony\src\Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList.php:430
  PHP  18. Doctrine\ORM\AbstractQuery-&gt;execute() ..\example.com\vendor\symfony\symfony\src\Symfony\Bridge\Doctrine\Form\ChoiceList\ORMQueryBuilderLoader.php:71
  PHP  19. Doctrine\ORM\Query-&gt;_doExecute() ..\example.com\vendor\doctrine\orm\lib\Doctrine\ORM\AbstractQuery.php:794
  PHP  20. Doctrine\ORM\Query\Exec\SingleSelectExecutor-&gt;execute() ..\example.com\vendor\doctrine\orm\lib\Doctrine\ORM\Query.php:286
  PHP  21. Doctrine\DBAL\Connection-&gt;executeQuery() ..\example.com\vendor\doctrine\orm\lib\Doctrine\ORM\Query\Exec\SingleSelectExecutor.php:50
  PHP  22. PDOStatement-&gt;execute() ..\example.com\vendor\doctrine\dbal\lib\Doctrine\DBAL\Connection.php:694
  </code></pre>
  
  <p>How to fix this error? Thank for your help.</p>
  
  <p>I have a complex form</p>
  
  <pre><code>public function buildForm(FormBuilderInterface $builder, array $options)
  {
  $builder
  -&gt;add('beds', 'choice', [
      'choices' =&gt; [
          '1' =&gt; '1',
          '2' =&gt; '2',
          '3' =&gt; '3',
          '4' =&gt; '4',
          '5' =&gt; '5',
          '6' =&gt; '6',
          '7' =&gt; '7',
          '8' =&gt; '8',
          '9' =&gt; '9+',
      ],
      'placeholder' =&gt; '',
  ])
  -&gt;add('baths', 'choice', [
      'choices' =&gt; [
          '1' =&gt; '1',
          '2' =&gt; '2',
          '3' =&gt; '3',
          '4' =&gt; '4',
          '5' =&gt; '5',
          '6' =&gt; '6',
          '7' =&gt; '7',
          '8' =&gt; '8',
          '9' =&gt; '9+',
      ],
      'placeholder' =&gt; '',
  ])
  -&gt;add('storey', 'choice', [
      'choices' =&gt; [
          '1' =&gt; '1',
          '2' =&gt; '2',
          '3' =&gt; '3',
          '4' =&gt; '4',
          '5' =&gt; '5',
          '6' =&gt; '6',
          '7' =&gt; '7',
          '8' =&gt; '8',
          '9' =&gt; '9+',
      ],
      'placeholder' =&gt; '',
      'required' =&gt; false,
  ])
  -&gt;add('title')
  -&gt;add('body')
  -&gt;add('password', 'repeated', [
      'type' =&gt; 'password',
      'invalid_message' =&gt; 'The password fields must match.',
      'options' =&gt; array('attr' =&gt; array('class' =&gt; 'password-field')),
      'required' =&gt; true,
      'first_options' =&gt; array('label' =&gt; 'Password'),
      'second_options' =&gt; array('label' =&gt; 'Repeat Password'),
  ])
  -&gt;add('province', 'entity', [
      'class' =&gt; 'AppBundle:Province',
      'property' =&gt; 'name',
      'placeholder' =&gt; ''
  ])
  -&gt;add('activity', 'entity', [
      'class' =&gt; 'AppBundle:Activity',
      'property' =&gt; 'name',
      'placeholder' =&gt; ''
  ])
  -&gt;add('unit', 'entity', [
      'class' =&gt; 'AppBundle:Unit',
      'property' =&gt; 'name',
      'placeholder' =&gt; ''
  ])
  -&gt;add('direction', 'entity', [
      'class' =&gt; 'AppBundle:Direction',
      'property' =&gt; 'name',
      'placeholder' =&gt; '',
      'required' =&gt; false
  ])
  -&gt;add('legal', 'entity', [
      'class' =&gt; 'AppBundle:Legal',
      'property' =&gt; 'name',
      'placeholder' =&gt; '',
      'required' =&gt; false
  ])
  -&gt;add('images', 'collection', [
      'type' =&gt; new PropertyImageType(),
      'allow_add' =&gt; true,
      'allow_delete' =&gt; true
  ])
  -&gt;add('amenities', 'entity', [
      'class' =&gt; 'AppBundle:Amenity',
      'property' =&gt; 'name',
      'expanded' =&gt; true,
      'multiple' =&gt; true,
      'query_builder' =&gt; function (EntityRepository $repository) {
          return $repository-&gt;createQueryBuilder('a')
              -&gt;from('AppBundle:Amenity', 'amenity')
              -&gt;where('a.type = 1');
      }
  ]);
  </code></pre>
  
  <p>And I use EventSubscriber to add some field dynamically</p>
  
  <pre><code>$builder-&gt;addEventSubscriber(new AddDistrictFieldSubscriber())
      -&gt;addEventSubscriber(new AddStreetFieldSubscriber())
      -&gt;addEventSubscriber(new AddWardFieldSubscriber())
      -&gt;addEventSubscriber(new AddProjectFieldSubscriber());
  
  class AddDistrictFieldSubscriber implements EventSubscriberInterface
  {
  
      /**
       * Returns an array of event names this subscriber wants to listen to.
       *
       * The array keys are event names and the value can be:
       *
       *  * The method name to call (priority defaults to 0)
       *  * An array composed of the method name to call and the priority
       *  * An array of arrays composed of the method names to call and respective
       *    priorities, or 0 if unset
       *
       * For instance:
       *
       *  * array('eventName' =&gt; 'methodName')
       *  * array('eventName' =&gt; array('methodName', $priority))
       *  * array('eventName' =&gt; array(array('methodName1', $priority), array('methodName2'))
       *
       * @return array The event names to listen to
       *
       * @api
       */
      public static function getSubscribedEvents()
      {
          return [
              FormEvents::PRE_SET_DATA =&gt; 'preSetData',
              FormEvents::PRE_SUBMIT =&gt; 'preSubmit',
          ];
      }
  
      public function preSetData(FormEvent $event)
      {
          $data = $event-&gt;getData();
          $form = $event-&gt;getForm();
  
          $province = $data-&gt;getProvince();
          $districts = $province === null ? [] : $province-&gt;getDistricts();
  
          $form-&gt;add('district', 'entity', [
              'class' =&gt; 'AppBundle:District',
              'property' =&gt; 'name',
              'placeholder' =&gt; '',
              'choices' =&gt; $districts,
          ]);
      }
  
      public function preSubmit(FormEvent $event)
      {
          $data = $event-&gt;getData();
          $form = $event-&gt;getForm();
  
          $province = array_key_exists('province', $data) ? $data['province'] : null;
  
          $form-&gt;add('district', 'entity', [
              'class' =&gt; 'AppBundle:District',
              'property' =&gt; 'name',
              'placeholder' =&gt; '',
              'query_builder' =&gt; function (EntityRepository $repository) use ($province) {
                  return $repository-&gt;createQueryBuilder('d')
                      -&gt;from('AppBundle:District', 'district')
                      -&gt;where('district.province = :province')
                      -&gt;setParameter('province', $province);
              }
          ]);
      }
  }
  
  class AddStreetFieldSubscriber implements EventSubscriberInterface
  {
  
      /**
       * Returns an array of event names this subscriber wants to listen to.
       *
       * The array keys are event names and the value can be:
       *
       *  * The method name to call (priority defaults to 0)
       *  * An array composed of the method name to call and the priority
       *  * An array of arrays composed of the method names to call and respective
       *    priorities, or 0 if unset
       *
       * For instance:
       *
       *  * array('eventName' =&gt; 'methodName')
       *  * array('eventName' =&gt; array('methodName', $priority))
       *  * array('eventName' =&gt; array(array('methodName1', $priority), array('methodName2'))
       *
       * @return array The event names to listen to
       *
       * @api
       */
      public static function getSubscribedEvents()
      {
          return [
              FormEvents::PRE_SET_DATA =&gt; 'preSetData',
              FormEvents::PRE_SUBMIT =&gt; 'preSubmit',
          ];
      }
  
      public function preSetData(FormEvent $event)
      {
          $data = $event-&gt;getData();
          $form = $event-&gt;getForm();
  
          $district = $data-&gt;getDistrict();
          $streets = $district === null ? [] : $district-&gt;getStreets();
  
          $form-&gt;add('street', 'entity', [
              'class' =&gt; 'AppBundle:Street',
              'property' =&gt; 'name',
              'placeholder' =&gt; '',
              'choices' =&gt; $streets,
              'required' =&gt; false,
          ]);
      }
  
      public function preSubmit(FormEvent $event)
      {
          $data = $event-&gt;getData();
          $form = $event-&gt;getForm();
  
          $district = array_key_exists('district', $data) ? $data['district'] : null;
  
          $form-&gt;add('street', 'entity', [
              'class' =&gt; 'AppBundle:Street',
              'property' =&gt; 'name',
              'placeholder' =&gt; '',
              'query_builder' =&gt; function (EntityRepository $repository) use ($district) {
                  return $repository-&gt;createQueryBuilder('s')
                      -&gt;from('AppBundle:Street', 'street')
                      -&gt;where('street.district = :district')
                      -&gt;setParameter('district', $district);
              }
          ]);
      }
  }
  </code></pre>
  
  <p>Databases tables:
  - province: id - name (70 records)
  - district: id - province_id - prefix - name (700 records)
  - street: id - district_id - prefix - name (17000 records)
  - ward: id - district_id - prefix - name (11000 records)
  ... and some more tables</p>