简体   繁体   中英

Symfony2 fos_rest_bundle param converter not calling entity constructor

I'm developing an API and have the following entity:

/**
 * Solicitud de registro.
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="DnD\RaHApiBundle\Repository\ApplicationRepository")
 */
class Application
{

  public function __construct()
  {
    $pending = new Event("PENDING", "APPLICATION");

    $this->status = new ArrayCollection($pending);
    $this->ownsVehicle = false;
    $this->resident = true;
    $this->timestamp = new DateTime();
  }

  /**
   * @var integer
   *
   * @ORM\Column(name="id", type="integer")
   * @ORM\Id
   * @ORM\GeneratedValue(strategy="AUTO")
   * @Groups({"application_info"})
   */
  private $id;

  ...

Notice the constructor. It sets some fields in my entity with their default values. Now my controller's action:

  /**
   * Crea una nueva solicitud de afiliacion
   * @return array
   *
   * @Post("applications")
   * @ParamConverter("application", converter="fos_rest.request_body")
   */
  public function postAction(Application $application)
  {
    $this->applicationsRepo->save($application);

    // It has no date, no status, no defaults!!!

    $view = $this->view($application, 200);
    $view->getSerializationContext()->setSerializeNull(true);
    $view->getSerializationContext()->setGroups(array('application_info'));
    return $this->viewHandler->handle($view);
  }

The $application object doesn't have its default values set, why is this? how can I make the converter call the constructor and set all default values?

I ran into the same problem. If you're sure that the default values won't be overwritten from the request body you can call the constructor explicitly.

$application->__construct();

In my case I just wanted to initialize all the ArrayCollection properties to prevent errors trying to access them so I didn't care about overwriting scalar values from the request.

I've also found that in

vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php

the buildFactory method is the source of the problem there. If you change:

return $reflectionClass->newInstanceWithoutConstructor();

to

return $reflectionClass->newInstance();

the param converter will return an Object whose constructor has been called. However this will fail if the constructor has required arguments. Of course you could fork doctrine and change this, but it might be overkill :-)

I think by switching JMS's default object constructor to the Doctrine one hte entity's constructor should be called:

services:
  jms_serializer.object_constructor:
    alias: jms_serializer.doctrine_object_constructor
    public: false

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM