Question

I'm currently trying to expose groups for an ajax call. If I user @Expose on each field it works like a charm but if I replace it with @Groups it throws the error recursion detected in JsonSerializationVisitor.php on line 29 and the results in my ajax return has a 'null' value.

Warning: json_encode() [function.json-encode]: recursion detected in /Applications/MAMP/htdocs/xxx-ref/vendor/jms/serializer/src/JMS/Serializer/JsonSerializationVisitor.php on line 29
{"datas":[{"datas":null,"errors":[],"redirect":null},{},{},{},{},{},{},{},{},{},{},{}],"errors":[],"redirect":null}

This is my call to the serializer =>

$context = new SerializationContext(false, 1);
$context->setSerializeNull(true);
$context->setGroups(array('details'));
$response->setContent($this->get('serializer')->serialize(array( 'datas'=>$datas, 'errors'=>$errors, 'redirect'=>$redirect), 'json', $context));

And this is the entity used

<?php

namespace XXX\CoreBundle\Entity\Geo;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use JMS\Serializer\Annotation\ExclusionPolicy;
use JMS\Serializer\Annotation\Exclude;
use JMS\Serializer\Annotation\Expose;
use JMS\Serializer\Annotation\Groups;

use XXX\CommonBundle\Entity\interfaces\TranslatableInterface;
use XXX\CoreBundle\Entity\Geo\Translation\AddressTranslation;
use XXX\CoreBundle\Proxy\AddressTranslatorProxy;

/**
 * @ORM\Entity(repositoryClass="XXX\CoreBundle\Repository\Geo\AddressRepository")
 * @ORM\HasLifecycleCallbacks()
 * @ORM\Table(name="geo_address", 
 *      indexes={@ORM\Index(name="address_idx", columns={"geolocation","formattedAddress","slug","valid"})})
 * @Gedmo\TranslationEntity(class="XXX\CoreBundle\Entity\Geo\Translation\AddressTranslation")
 * @ExclusionPolicy("all")
*/
class Address {    

   /**
     * @ORM\Id
     * @ORM\Column(type="bigint")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="XXX\CoreBundle\Entity\Geo\Country", inversedBy="addresses", fetch="EXTRA_LAZY")
     * @ORM\JoinColumn(name="country_id", referencedColumnName="id")
     * 
     */
    protected $country;


    /**
     * @ORM\Column(type="string", length=128, unique=true)
     * @Gedmo\Slug(fields={"formattedAddress"})
     * 
     */
    protected $slug;

    /**
     * @ORM\Column(type="string", length=255, nullable=false)
     * @Gedmo\Translatable(fallback=true)
     * 
     */
    protected $formattedAddress;

    /**
     * @ORM\Column(type="point", unique=true)
     * 
     */
    protected $geolocation;

    /**
     * @ORM\ManyToOne(targetEntity="XXX\CoreBundle\Entity\Geo\Street", inversedBy="addresses")
     * @ORM\JoinColumn(name="street_id", referencedColumnName="id")
     * 
     */
    protected $street;

    /**
     * @ORM\Column(type="string", length=32, nullable=true)
     * @Groups({"details"})
     */
    protected $number;

    /**
     * @ORM\Column(type="string", length=32, nullable=true)
     * 
     */
    protected $postbox;

    /**
     * @ORM\Column(type="string", length=16, nullable=true)
     * 
     */
    protected $postalCode;

    /**
     * @ORM\ManyToOne(targetEntity="XXX\CoreBundle\Entity\Geo\Locality", inversedBy="addresses")
     * @ORM\JoinColumn(name="locality_id", referencedColumnName="id", nullable=true)
     *  
     */
    protected $locality;

    /**
     * @ORM\ManyToOne(targetEntity="XXX\CoreBundle\Entity\Geo\Sublocality", inversedBy="addresses")
     * @ORM\JoinColumn(name="sublocality_id", referencedColumnName="id", nullable=true)
     * 
     */
    protected $sublocality;
    /**
     * @ORM\ManyToOne(targetEntity="XXX\CoreBundle\Entity\Geo\AdministrativeAreaLevel1", inversedBy="addresses")
     * @ORM\JoinColumn(name="al1_id", referencedColumnName="id")
     * 
     */
    protected $administrativeAreaLevel1;

    /**
     * @ORM\ManyToOne(targetEntity="XXX\CoreBundle\Entity\Geo\AdministrativeAreaLevel2", inversedBy="addresses")
     * @ORM\JoinColumn(name="al2_id", referencedColumnName="id")
     * 
     */
    protected $administrativeAreaLevel2;

    /**
     * @ORM\ManyToOne(targetEntity="XXX\CoreBundle\Entity\Geo\AdministrativeAreaLevel3", inversedBy="addresses")
     * @ORM\JoinColumn(name="al3_id", referencedColumnName="id")
     * 
     */
    protected $administrativeAreaLevel3;

    /**
     * @ORM\Column(type="string", length=255)
     * 
     */
    protected $geolocationType;

    /**
     * @ORM\Column(type="point")
     * 
     */
    protected $viewportSouthWest;

    /**
     * @ORM\Column(type="point")
     * 
     */
    protected $viewportNorthEast;

    /** 
     * @ORM\Column(type="boolean", nullable=false)
     * 
     *  
     */
    protected $valid;

    /**
     * @ORM\OneToMany(targetEntity="XXX\CoreBundle\Entity\Geo\ChangeRequest", mappedBy="address")
     */
    protected $changeRequest;

    /**
     * @ORM\OneToMany(targetEntity="XXX\CoreBundle\Entity\Ads\Hybrid", mappedBy="address")
     */
    protected $hybrids;

    /**
     * @ORM\OneToMany(
     *     targetEntity="XXX\CoreBundle\Entity\Geo\Translation\AddressTranslation",
     *     mappedBy="object",
     *     cascade={"persist","remove"}, fetch="EXTRA_LAZY"
     * )
     * @ORM\JoinColumn(name="translatable_id", referencedColumnName="id", nullable=true)
     */
    protected $translations;

    function __construct() {
        $this->hybrids = new \Doctrine\Common\Collections\ArrayCollection();
        $this->changeRequest = new \Doctrine\Common\Collections\ArrayCollection();
        $this->translations = new \Doctrine\Common\Collections\ArrayCollection();
        $this->valid = false;
    }

    public function getLocalityAsText() {
        if ($this->postalCode != null) {
            return strtolower( $this->country->getIso3166Alpha2()."-".$this->postalCode );
        } else {
            return strtolower( $this->country->getIso3166Alpha2()."-".$this->locality->getName() );
        }

    }

    public function __toString() {
        return $this->getFormattedAddress();
    }

    public function translate($locale = null)
    {
        return new AddressTranslatorProxy(
                $this,
                $locale,
                array('formattedAddress'),
                'XXX\CoreBundle\Entity\Geo\Translation\AddressTranslation',
                $this->translations
            );

    }

    public function isPrecise() {
       return  ( $this->getGeolocationType() === 'ROOFTOP' || $this ->getGeolocationType() === 'RANGE_INTERPOLATED' );
    }

    public function getTranslations()
    {
        return $this->translations;
    }

    public function addTranslation(AddressTranslation $t)
    {
        if (!$this->translations->contains($t)) {
            $this->translations[] = $t;
            $t->setObject($this);
        }
    }

    public function removeTranslation(AddressTranslation $t)
    {
        if ($this->translations->contains($t)) {
            $this->translations->remove($t);
        }
    }

    public function getHybrids() {
        return $this->hybrids;
    }

    public function setHybrids($hybrids) {
        $this->hybrids = $hybrids;
        return $this;
    }

    public function getFormattedAddress($locale=null) {
        return $this->formattedAddress;
    }

    public function getId() {
        return $this->id;
    }

    public function getGeolocation() {
        return $this->geolocation;
    }

    public function setGeolocation($geolocation) {
        $this->geolocation = $geolocation;
        return $this;
    }

    public function getStreet() {
        return $this->street;
    }

    public function setStreet($street) {
        $this->street = $street;
        return $this;
    }

    public function getNumber() {
        return $this->number;
    }

    public function setNumber($number) {
        $this->number = $number;
        return $this;
    }

    public function getPostbox() {
        return $this->postbox;
    }

    public function setPostbox($postbox) {
        $this->postbox = $postbox;
        return $this;
    }

    public function getLocality() {
        return $this->locality;
    }

    public function setLocality($locality) {
        $this->locality = $locality;
        return $this;
    }

    public function getSublocality() {
        return $this->sublocality;
    }

    public function setSublocality($sublocality) {
        $this->sublocality = $sublocality;
        return $this;
    }

    public function getCountry() {
        return $this->country;
    }

    public function setCountry($country) {
        $this->country = $country;
        return $this;
    }

    public function getAdministrativeAreaLevel1() {
        return $this->administrativeAreaLevel1;
    }

    public function setAdministrativeAreaLevel1($administrativeAreaLevel1) {
        $this->administrativeAreaLevel1 = $administrativeAreaLevel1;
        return $this;
    }

    public function getAdministrativeAreaLevel2() {
        return $this->administrativeAreaLevel2;
    }

    public function setAdministrativeAreaLevel2($administrativeAreaLevel2) {
        $this->administrativeAreaLevel2 = $administrativeAreaLevel2;
        return $this;
    }

    public function getAdministrativeAreaLevel3() {
        return $this->administrativeAreaLevel3;
    }

    public function setAdministrativeAreaLevel3($administrativeAreaLevel3) {
        $this->administrativeAreaLevel3 = $administrativeAreaLevel3;
        return $this;
    }

    public function getGeolocationType() {
        return $this->geolocationType;
    }

    public function setGeolocationType($geolocationType) {
        $this->geolocationType = $geolocationType;
        return $this;
    }

    public function getViewportSouthWest() {
        return $this->viewportSouthWest;
    }

    public function setViewportSouthWest($viewportSouthWest) {
        $this->viewportSouthWest = $viewportSouthWest;
        return $this;
    }

    public function getViewportNorthEast() {
        return $this->viewportNorthEast;
    }

    public function setViewportNorthEast($viewportNorthEast) {
        $this->viewportNorthEast = $viewportNorthEast;
        return $this;
    }

    public function getChangeRequest() {
        return $this->changeRequest;
    }

    public function setChangeRequest($changeRequest) {
        $this->changeRequest = $changeRequest;
        return $this;
    }

    public function setFormattedAddress($formattedAddress) {
        $this->formattedAddress = $formattedAddress;
        return $this;
    }
    public function getPostalCode() {
        return $this->postalCode;
    }

    public function setPostalCode($postalCode) {
        $this->postalCode = $postalCode;
        return $this;
    }

    public function getValid() {
        return $this->valid;
    }

    public function setValid($valid) {
        $this->valid = $valid;
        return $this;
    }

    public function getSlug() {
        return $this->slug;
    }

    public function setSlug($slug) {
        $this->slug = $slug;
        return $this;
    }


}
Was it helpful?

Solution

I answered my own question

I just needed to add

@Expose

before the Groups annotation.

/**
 * @ORM\Column(type="string", length=32, nullable=true)
 * @Expose
 * @Groups({"details"})
 */
protected $number;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top