Hoi,

Ik heb een nieuw Symfony2-project waarbij ik een bestaande database automatisch heb laten mappen naar entiteiten. Ik wil graag een RESTapi gaan maken met dit Symfony-project, dus heb ik de volgende controller:
<?php
namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;

class APIController extends Controller
{
    /**
     * @Route("/api/{type}/{id}", name="get")
     * @Method("GET")
     */
    public function getAction($type, $id, Request $request)
    {
        $response = null;

        $serializer = new Serializer(
            array(
                new ObjectNormalizer()
            ),
            array(
                new XmlEncoder(),
                new JsonEncoder()
            )
        );

        $repository = $this->getDoctrine()->getRepository('AppBundle:' . $type);

        $entity = $repository->find($id);
        $test = $serializer->serialize($entity, 'json');

        $response = new Response($serializer->serialize($entity, 'json'));
        $response->headers->set('Content-Type', 'application/json');

        return $response;
    }
}
?>

Ik heb wel een deel weggelaten, het gaat namelijk om het volgende. Als ik nu /api/Ride/1 opvraag, dan krijg ik de volgende exception:
Runtime Notice: Accessing static property Proxies\__CG__\AppBundle\Entity\Route::$lazyPropertiesDefaults as non static

Deze Ride heeft een referentie naar Route. Deze entiteiten zien er zo uit: (getters en setters weggelaten)
<?php
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Ride
 *
 * @ORM\Table(name="ride", indexes={@ORM\Index(name="route", columns={"route"})})
 * @ORM\Entity
 */
class Ride
{
    /**
     * @var \DateTime
     *
     * @ORM\Column(name="date", type="date", nullable=false)
     */
    private $date;

    /**
     * @var string
     *
     * @ORM\Column(name="description", type="string", length=50, nullable=true)
     */
    private $description;

    /**
     * @var boolean
     *
     * @ORM\Column(name="retour", type="boolean", nullable=true)
     */
    private $retour;

    /**
     * @var boolean
     *
     * @ORM\Column(name="active", type="boolean", nullable=false)
     */
    private $active;

    /**
     * @var integer
     *
     * @ORM\Column(name="ridenumber", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $ridenumber;

    /**
     * @var \AppBundle\Entity\Route
     *
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Route")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="route", referencedColumnName="routenumber")
     * })
     */
    private $route;
}
?>

<?php
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Route
 *
 * @ORM\Table(name="route")
 * @ORM\Entity
 */
class Route
{
    /**
     * @var string
     *
     * @ORM\Column(name="from", type="string", length=50, nullable=false)
     */
    private $from;

    /**
     * @var string
     *
     * @ORM\Column(name="addressfrom", type="string", length=50, nullable=false)
     */
    private $addressfrom;

    /**
     * @var string
     *
     * @ORM\Column(name="postalcodefrom", type="string", length=7, nullable=false)
     */
    private $postalcodefrom;

    /**
     * @var string
     *
     * @ORM\Column(name="to", type="string", length=50, nullable=false)
     */
    private $to;

    /**
     * @var string
     *
     * @ORM\Column(name="addressto", type="string", length=50, nullable=false)
     */
    private $addressto;

    /**
     * @var string
     *
     * @ORM\Column(name="postalcodeto", type="string", length=7, nullable=false)
     */
    private $postalcodeto;

    /**
     * @var string
     *
     * @ORM\Column(name="distance", type="decimal", precision=5, scale=2, nullable=false)
     */
    private $distance;

    /**
     * @var boolean
     *
     * @ORM\Column(name="active", type="boolean", nullable=false)
     */
    private $active;

    /**
     * @var integer
     *
     * @ORM\Column(name="routenumber", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $routenumber;
}
?>

Ik vind het vooral een vage foutmelding aangezien deze uit Symfony zelf komt. Deze foutmelding krijg ik bij andere entiteiten ook (zoals Cursist die een Person is).

Weet iemand wat ik moet doen om dit op te lossen?

Roel
Ik heb de properties van zowel Ride als Route omgezet van 'private' naar 'protected'. Ook heb ik 'to' en 'fro' omgezet naar respectievelijk 'nameto' en 'fromto'. Daarna de cache geleegd. Nog steeds krijg ik de volgende foutmelding:
Runtime Notice: Accessing static property Proxies\__CG__\AppBundle\Entity\Route::$lazyPropertiesDefaults as non static
@Roel,

Heb je het ook geprobeerd met fetch="EAGER", nadat je properties omgezet had naar protected?
Hulde! Het werkt nu ik fetch="EAGER" heb toegevoegd. Eerder werkte dit niet. Ik ga straks uitzoeken wat er precies voor heeft gezorgd dat dit eerder niet werkte en nu wel.
Hartstikke bedankt allebei voor nu!
@Roel

Graag gedaan :) De reden waarom het niet werkte is omdat jij jouw properties op 'private' had staan.
Ik moet je helaas teleurstellen. Ik heb 'nameto' en 'fromto' teruggewijzigd naar'to' en 'from' en de protected properties weer private gemaakt. Het lijkt nog steeds te werken. Als ik fetch="EAGER" weghaal, dan gaat het weer fout. Zet ik het weer terug, dan gaat het weer goed.

Ik snap alleen nog steeds niet waarom het niet direct werkte toen ik fetch="EAGER" toevoegde. Dat ga ik straks nog eens nader onderzoeken.
@Roel,

Misschien omdat je eerst jouw cache niet opgeschoond had? Normaal hoort hij gewoon op 'protected' te staan, als je wilt serializen in Symfony, maar ik kan me natuurijk vergissen, want ik ben zelf eigenlijk nog maar een 'leerling' in Symfony :P. Het lukt nu in ieder geval en bleek fetch="EAGER" toch wel de juiste.
Ik heb het probleem gevonden! Deze stappen heb ik de eerste keer gevolgd:
http://symfony.com/doc/current/cookbook/doctrine/reverse_engineering.html

Toen kreeg ik dus een map Resources met mapping-informatie. Toen ik stap voor stap alles ging nalopen, kwam ik erachter dat nadat ik deze map verwijderde, het probleem ook niet meer voorkwam. Het blijkt dus dat ik in het bijbehorende XML-bestand ook fetch="EAGER" moest toevoegen aan de relatie met Route.

Kan iemand mij vertellen waarom ik dan nu nog steeds annotations bij m'n klassen heb?

[size=xsmall]Toevoeging op 17/09/2015 17:22:39:[/size]

Gelijk even geprobeerd de annotations weg te halen. Het lijkt nog steeds te werken. Wat is het nut van deze annotations nu nog?
Blijkbaar is er voor gekozen om XML en annotations aan te maken? Annotations worden het meest gebruikt icm met Doctrine maar je mag uiteindelijk zelf kiezen wat je prettig vindt. Ik vind zelf het fijne aan annotations dat je geen apart config file hoeft te openen maar dat ze gewoon bij je properties staan en zo ook met de routes bij je Action methods in de controllers.

Ik geef zelf ook de voorkeur aan annotations, om dezelfde reden als jij.
In de tutorial wordt echter standaard XML gebruikt en krijg je een tip als je YAML wil gebruiken. Hoe zit dit dan voor annotations? Weet jij of en hoe dat eventueel kan?
annotations voor de serializer?

in config.yml:

framework:
    serializer:      { enable_annotations: true }

Reageren