I'm trying to deserialize an entity with a relationship using the symfony serializer component. This is my entity:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Document
*
* @ORM\Table(name="document")
* @ORM\Entity(repositoryClass="AppBundle\Repository\DocumentRepository")
*/
class Document
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="Genre", inversedBy="documents")
* @ORM\JoinColumn(name="id_genre", referencedColumnName="id")
*/
private $genre;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=100)
*/
private $name;
//getters and setters down here
...
}
And the Genre entity:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Genre
*
* @ORM\Table(name="genre")
* @ORM\Entity(repositoryClass="AppBundle\Repository\GenreRepository")
*/
class Genre
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=50, nullable=true)
*/
private $name;
/**
* @ORM\OneToMany(targetEntity="Document", mappedBy="genre")
*/
private $documents;
public function __construct()
{
$this->documents= new ArrayCollection();
}
//getters and setters down here
....
}
In my controller action right now I'm trying this:
$encoders = array(new JsonEncoder());
$normalizers = array(new ObjectNormalizer());
$serializer = new Serializer($normalizers, $encoders);
$document = $serializer->deserialize($request->getContent(), 'AppBundle\Entity\Document', 'json');
And my json data:
{"name": "My document", "genre": {"id": 1, "name": "My genre"}}
But I got the next error:
Expected argument of type "AppBundle\Entity\Genre", "array" given (500 Internal Server Error)
Is possible to deserialize a json request with an entity with relations inside?
Thanks in advace.
If you are using JMS Serializer, you can use this code and the serializer will search for relation in database.
services.yml
AppBundle\Services\JMSDoctrineObjectConstructor.php
For anyone who is working on this in '18. I've managed to get this working using two different approaches.
The associated entities I'm working with.
Method 1: Using Form Classes
Method 2: A Custom Normalizer
The PropertyInfo Component needs to be enabled.
Register the custom normalizer.
The custom normalizer.
Our controller's create action.
This has worked for me. I received inspiration from: https://medium.com/@maartendeboer/using-the-symfony-serializer-with-doctrine-relations-69ecb17e6ebd
I modified the normalizer to allow me to send the category as a child json object which is converted to a child array when the data is decoded from json. Hopefully this helps someone.
This is what the Symfony documentation calls "Recursive Denormalization", starting from version 3.3 up to the actual master, 4.0.
In order for Symfony to find the property types of the serialized objects, it needs to use the PropertyInfo component, which, as @slk500 stated in his answer, has to be activated in the framework configuration.
So, if you are using the full framework, all you need to do in order to deserialize nested json objects is this:
1.Enable the serializer and the property info components in config.yml:
The default features of these components were enough for my needs.
Autowiring takes care of the basic service declaration, so unless you need specific normalizers, you don't even have to edit the
services.yml
configuration file. Depending on your use cases, you may have to enable specific features. Check the Serializer and PropertyInfo documentation for (hopefully) more specific use cases.It works now.You have to enable property_info in config.yml:
Yes and no. First, you shouldn't re-create a new instance of the serializer in your controller but use the
serializer
service instead.Second, no it's not possible out of the box with Symfony serializer. We are doing it in https://api-platform.com/ but there is a bit of magic there. That said, a PR has been made to support it: https://github.com/symfony/symfony/pull/19277