A circular reference has been detected when serializing the object of class "App\Entity\User" (configured limit: 1)

eronn picture eronn · Dec 10, 2019 · Viewed 16.2k times · Source

I am faced with a problem that gives me this error:

A circular reference has been detected when serializing the object of class "App\Entity\User" (configured limit: 1)

I have an Enterprise entity that has mission orders, vehicles, and users.

An orders entity that has a relationship with a User, Company, and Vehicle.

And a User entity that has a relationship with orders and company.

So I have this: Entreprise.php

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


    /**
     * @ORM\OneToMany(targetEntity="App\Entity\User", mappedBy="entreprise", orphanRemoval=true)
     */
    private $users;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Vehicule", mappedBy="entreprise", orphanRemoval=true)
     */
    private $vehicules;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\OrdreMission", mappedBy="entreprise", orphanRemoval=true)
     */
    private $ordreMissions;

OrdreMission.php:

class OrdreMission
{

    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * Agent qui réalisera la mission
     * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="ordreMissions")
     * @ORM\JoinColumn(nullable=false)
     */
    private $user;


    /**
     * Immatriculation de la voiture de service
     * @ORM\ManyToOne(targetEntity="App\Entity\Vehicule")
     */
    private $vehicule;



    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Entreprise", inversedBy="ordreMissions")
     * @ORM\JoinColumn(nullable=false)
     */
    private $entreprise;

Vehicule.php:

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

    /**
     * Marque du véhicule
     * @ORM\Column(type="string", length=255)
     */
    private $marque;

    /**
     * Modèle du véhicule
     * @ORM\Column(type="string", length=255)
     */
    private $modele;

    /**
     * Immatriculation du véhicule
     * @ORM\Column(type="string", length=255)
     * @MaxDepth(2)
     */
    private $immatriculation;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Entreprise", inversedBy="vehicules")
     * @ORM\JoinColumn(nullable=false)
     * @MaxDepth(2)
     */
    private $entreprise;

User.php:

class User implements UserInterface, Serializable
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * Adresse email de l'utilisateur
     * @ORM\Column(type="string", length=180, unique=true)
     * @Assert\NotBlank()
     * @Assert\Email(message="Veuillez renseigner un email valide")
     */
    private $email;

    /**
     * Rôles de l'utilisateur
     * @ORM\Column(type="json")
     */
    private $roles = [];


    /**
     * Ordres de mission de l'utilisateur
     * @ORM\OneToMany(targetEntity="App\Entity\OrdreMission", mappedBy="user")
     */
    private $ordreMissions;


    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Entreprise", inversedBy="users")
     * @ORM\JoinColumn(nullable=false)
     */
    private $entreprise;

/**
 * String representation of object
 * @link http://php.net/manual/en/serializable.serialize.php
 * @return string the string representation of the object or null
 */
public function serialize()
{
    return serialize([
        $this->id,
        $this->email,
        $this->password,
    ]);
}

/**
 * Constructs the object
 * @link http://php.net/manual/en/serializable.unserialize.php
 * @param string $serialized <p>
 * The string representation of the object.
 * </p>
 * @return void
 */
public function unserialize($serialized)
{
    list (
        $this->id,
        $this->email,
        $this->password,
        ) = unserialize($serialized);
}

When I want to add a new vehicle, I get the error:

A circular reference has been detected when serializing the object of class "App\Entity\User" (configured limit: 1)

I saw on the Internet that I had to do something with a "maxdepth", but I do not understand what I have to do and where exactly

This is the function controller that I use to add a Vehicle Object and send it:

   /**
     * Pour créer un nouveau véhicule
     * 
     * @Route("/chef-service/ordres-mission/new/new-vehicule", name="vehicule_create")
     * @IsGranted({"ROLE_CHEF_SERVICE"})
     * @Method({"POST"})
     * @return Response
     */
    public function createVehicule(Request $request, EntityManagerInterface $manager)
    {
        $vehicule = new Vehicule();
        $vehicule->setEntreprise($this->adminService->getEntreprise());

        $form = $this->createForm(VehiculeType::class, $vehicule, [
            'action' => $this->generateUrl($request->get('_route'))
        ]);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {

            $encoders = array(new XmlEncoder(), new JsonEncoder());
            $normalizers = array(new ObjectNormalizer());
            $serializer = new Serializer($normalizers, $encoders);
            $manager->persist($vehicule);
            $manager->flush();

            $result = $serializer->normalize(
                [
                    'code' => 200,
                    'message' => 'OK',
                    'vehicule' => $vehicule,
                ],
                null,
                [AbstractObjectNormalizer::ENABLE_MAX_DEPTH => true]
            );
            
            $jsonContent = $serializer->serialize(
                $result,
                'json'
            );
            return new Response($jsonContent);

        }

        return $this->render('ordre_mission/partials/newVehicule.html.twig', [
            'formVehicule' => $form->createView(),
        ]);
    }

Answer

Omar J Fry picture Omar J Fry · Dec 12, 2019

Try to avoid circular reference by using Serialization Groups (work for both Symfony Serializer and jms Serializer). Example when your serialize "User" don't serialize "users" from other entity.

User

class User 
{

/**
 * @Groups("user")
 * @ORM\Id()
 * @ORM\GeneratedValue()
 * @ORM\Column(type="integer")
 */
private $id;

/**
 * @Groups("user")
 * @ORM\ManyToOne(targetEntity="App\Entity\Entreprise", inversedBy="users")
 * @ORM\JoinColumn(nullable=false)
 */
private $entreprise;
}

Entreprise

class Entreprise
{
/**
 * @Groups("entreprise")
 * @ORM\Id()
 * @ORM\GeneratedValue()
 * @ORM\Column(type="integer")
 */
private $id;


/**
 * @Groups("user_detail")
 * @ORM\OneToMany(targetEntity="App\Entity\User", mappedBy="entreprise", orphanRemoval=true)
 */
private $users;

And then

$json = $serializer->serialize(
    $user,
    'json', ['groups' => ['user','entreprise' /* if you add "user_detail" here you get circular reference */]
);

However you have two more option either use Handling Circular References or use Handling Serialization Depth