Symfony REST api - Entity association field -> value is not valid
<p>In Symfony I'm writing an API for Angular2. I use the FOSRestBundle with the JMSSerializerBundle. Now, I have an entity "User" that has an entity field "address" with a OneToOne association. And I'm having trouble saving the address of the user.</p>

<p>So I first do a GET of the user object and it returns the whole object with the address as json. Then I do PUT request with that exact same object. In my PUT function I use a Symfony form to validate the data and there it returns an error:</p>

<pre><code>{
  "children": {
    "address": {
      "errors": [
        "This value is not valid."
      ]
    }
  }
}
</code></pre>

<p>I have some other fields on my User entity and those are saved perfectly when I leave out the address field in my form-builder. BTW: I left out those other fields to not overload the amount of code.</p>

<p>I use these versions:</p>

<ul>
<li>symfony: 3.1</li>
<li>jms/serializer: 1.1</li>
<li>friendsofsymfony/rest-bundle: 2.0</li>
</ul>

<p>I've been looking for 2 days now and I can't find anything that helps me with this issue. I use the date transformations like FOSRestBundle says: <a href="http://symfony.com/doc/current/bundles/FOSRestBundle/2-the-view-layer.html#data-transformation" rel="nofollow">http://symfony.com/doc/current/bundles/FOSRestBundle/2-the-view-layer.html#data-transformation</a></p>

<p>I hope I formulated my question good enough and gave enough info.</p>

<p>Here is my simplified code:</p>

<p>User class:</p>

<pre><code>use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as JMS;

/**
 * @ORM\Entity
 */
class User
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\OneToOne(targetEntity="Address", cascade={"persist", "remove"}, orphanRemoval=true)
     * @JMS\Type("AppBundle\Entity\Address")
     */
    private $address;
</code></pre>

<p>Address class:</p>

<pre><code>use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class Address
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string")
     */
    private $street;

    /**
     * @ORM\Column(type="string")
     */
    private $number;

    /**
     * @ORM\Column(type="string")
     */
    private $postalCode;

    /**
     * @ORM\Column(type="string")
     */
    private $city;

    /**
     * @ORM\Column(type="string")
     */
    private $country;
</code></pre>

<p>UserType class:</p>

<pre><code>use FOS\RestBundle\Form\Transformer\EntityToIdObjectTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class UserType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // Data transformation needed for relationship entities
        $addressTransformer = new EntityToIdObjectTransformer($options['em'], 'AppBundle:Address');

        $builder
            -&gt;add($builder-&gt;create('address', TextType::class)-&gt;addModelTransformer($addressTransformer))
        ;
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver-&gt;setDefaults(array(
            'data_class' =&gt; 'AppBundle\Entity\User',
            'csrf_protection'   =&gt; false,
            'allow_extra_fields' =&gt; true,
            'em' =&gt; null
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'user';
    }
}
</code></pre>

<p>UserController class:</p>

<pre><code>use AppBundle\Entity\User;
use AppBundle\Form\UserType;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\View\View;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;

/**
 * Class UserController
 * @package AppBundle\Controller
 */
class UserController extends Controller
{
    /**
     * @Rest\View
     * @Route("/users/{id}")
     * @Method("PUT")
     */
    public function putAction(Request $request, $id)
    {
        $user = $this-&gt;getEntity($id);
        $form = $this-&gt;createForm(UserType::class, $user, array(
            'method' =&gt; 'PUT',
            'em' =&gt; $this-&gt;getDoctrine()-&gt;getManager()
        ));

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

        if ($form-&gt;isValid()) {
            $em = $this-&gt;getDoctrine()-&gt;getManager();

            $em-&gt;persist($user);
            $em-&gt;flush();

            $response = new Response();
            $response-&gt;setStatusCode(204);
            $response-&gt;setContent('User saved!');

            return $response;
        }

        return View::create($form, 400);
    }


    /**
     * @Rest\View
     * @Route("/users/{id}", requirements={"id": "\d+"})
     * @Method("GET")
     */
    public function getAction($id)
    {
        $user = $this-&gt;getEntity($id);

        return array('user' =&gt; $user);
    }

    /**
     * Get the User entity object by the given ID and return it
     *
     * @param $id
     *
     * @return User
     */
    private function getEntity($id)
    {
        $user = $this-&gt;getDoctrine()-&gt;getRepository('AppBundle:User')-&gt;find($id);

        if (!$user instanceof User) {
            throw new NotFoundHttpException('User not found');
        }

        return $user;
    }
</code></pre>

<p>And the json-object that I GET and PUT looks like this:</p>

<pre><code>{
"user":
    {
        "id":1,
        "address": {
            "id":1,
            "street":"Teststreet",
            "number":"1",
            "postalCode":"9999",
            "city":"Citytest",
            "country":"Countrytest"
        }
    }
}
</code></pre>

<p>my config.yml:</p>

<pre><code>fos_rest:
    param_fetcher_listener: true
    body_listener:
        array_normalizer: fos_rest.normalizer.camel_keys
    format_listener:
        rules:
            path: ^/
            fallback_format: json
            prefer_extension: false
            priorities: [json, xml]
    body_converter:
        enabled:              false
        validate:             false
    view:
        view_response_listener: force
        formats:
            json: true
            xml: true
        templating_formats:
            html: true
        force_redirects:
            html: true
        failed_validation: HTTP_BAD_REQUEST
        default_engine: twig
        mime_types:
            json: ['application/json', 'application/json;version=1.0', 'application/json;version=1.1']
    routing_loader:
        default_format: json
    serializer:
        serialize_null: true

nelmio_api_doc: ~

jms_serializer:
    metadata:
        directories:
            FOSUB:
                namespace_prefix: "FOS\\UserBundle"
                path: "%kernel.root_dir%/serializer/FOSUserBundle"
</code></pre>