Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'Circular reference has been detected' error when serializing many-to-many-associated objects

Since upgrading to Symfony 2.7, I seem to keep getting 'circular reference has been detected' errors when attempting to serialize an array of contacts associated with a given group. They're setup in a many-to-many association (one group has many contacts; one contact has many group-associations).

Now, I followed the guide for using serialization groups as per the 2.7 upgrade post, but still seem to get the error. My controller code for this is currently as follows:

$group = $this->getDoctrine()
   ->getRepository('TwbGroupsBundle:ContactGroup')
   ->find($id);
$groupContacts = $group->getContacts();

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

$json = $serializer->serialize($groupContacts, 'json', array(
    'groups' => array('public')
));

When running $serializer->serialize(), I get the CircularReferenceException after 1 circular reference. So far I have my Contact entity configured like so, with the @Groups annotations:

/**
 * Contact
 *
 * @ORM\Table(name="tblContacts")
 * @ORM\Entity(repositoryClass="Twb\Bundle\ContactsBundle\Entity\Repository\ContactRepository")
 */
class Contact implements ContactInterface
{
    /**
     * @var string
     *
     * @ORM\Column(name="ContactName", type="string", length=50, nullable=true)
     * @Groups({"public"})
     */
    private $contactname;

    /**
     * @var integer
     *
     * @ORM\Column(name="ContactID", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     * @Groups({"public"})
     */
    private $contactid;

    /**
     * 
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="Twb\Bundle\GroupsBundle\Entity\ContactGroup", inversedBy="contacts")
     * @ORM\JoinTable(name="tblContactsGroupsAssignments", 
     *      joinColumns={@ORM\JoinColumn(name="contactId", referencedColumnName="ContactID")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="contactGroupId", referencedColumnName="id")}
     *  )
     */
    protected $contactGroups;

    // ...getters/setters and so on
}

And my ContactGroup entity:

/**
 * ContactGroup
 *
 * @ORM\Table(name="tblContactsGroups")
 * @ORM\Entity
 */
class ContactGroup
{
    // ...

    /**
     * 
     * @var Contact
     * 
     * @ORM\ManyToMany(targetEntity="Twb\Bundle\ContactsBundle\Entity\Contact", mappedBy="contactGroups")
     */
    private $contacts;

    // ...
}

Is there something I'm missing here to get around the circularity problem? Many thanks.

like image 326
Jonathan Avatar asked Oct 12 '15 20:10

Jonathan


2 Answers

It looks like something wrong with config. You have to enable serialization groups annotation:

# app/config/config.yml
framework:
# ...
serializer:
    enable_annotations: true

And proper use statement has to be present in ContactGroup entity class

use Symfony\Component\Serializer\Annotation\Groups;
like image 193
RashitKh Avatar answered Nov 09 '22 08:11

RashitKh


    $normalizers->setCircularReferenceHandler(function ($object) {
        return $object->getId();
    });

Just add it after you make the instance of your objectNormalizer ;

like image 28
Hatem Sahli Avatar answered Nov 09 '22 08:11

Hatem Sahli