序列化类“App\Entity\User”的对象时检测到循环引用(配置限制:1)

ero*_*onn 7 serialization reference circular-dependency depth symfony

我遇到了一个给我这个错误的问题:

序列化类“App\Entity\User”的对象时检测到循环引用(配置限制:1)

我有一个企业实体,其中包含任务订单、车辆和用户。

与用户、公司和车辆有关系的订单实体。

和一个与订单和公司有关系的用户实体。

所以我有这个: 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;
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

车辆.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;
Run Code Online (Sandbox Code Playgroud)

用户.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);
}
Run Code Online (Sandbox Code Playgroud)

当我想添加一辆新车时,出现错误:

序列化类“App\Entity\User”的对象时检测到循环引用(配置限制:1)

我在互联网上看到我必须用“maxdepth”做一些事情,但我不明白我必须做什么以及具体在哪里

这是我用来添加车辆对象并发送它的功能控制器:

   /**
     * 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(),
        ]);
    }
Run Code Online (Sandbox Code Playgroud)

num*_*web 16

对我来说,当我使用 API 平台时会发生此错误(可能与此案例无关,但可能对其他人有帮助),我必须在这里遵循此评论

这是因为实体没有用@ApiResource标记,所以它不被API平台处理(它是由Symfony平台处理),并且由于存在循环引用,所以会抛出错误。如果此实体是 API 资源,则会自动处理循环引用。如果不想使其成为资源,则需要自己注册循环引用处理程序: https: //symfony.com/doc/current/components/serializer.html#handling-circular-references


Tom*_*mas 10

就我而言,我修复了注入序列化器服务,而不是在控制器方法中创建新的序列化器实例。

use Symfony\Component\Serializer\SerializerInterface;

//...
public function createOrder(Request $request, SerializerInterface $serializer)
{
    //...
    $json = $serializer->serialize($order, 'json', ['groups' => ['normal']]);
    //...
}
Run Code Online (Sandbox Code Playgroud)


小智 8

如果子实体有一个父实体,并且您不想将其作为序列化中的另一个“子实体”..那么您可以尝试使用“忽略” use Symfony\Component\Serializer\Annotation\Ignore;

$user->messages(): // 用户有关系为 oneToMany 的消息

然后在消息中添加忽略到$user:

class Message
// ...
/** @Ignore() */
$user;
Run Code Online (Sandbox Code Playgroud)


Oma*_*bel 7

尝试通过使用序列化组来避免循环引用(适用于 Symfony Serializer 和 jms Serializer)。当您序列化“用户”不从其他实体序列化“用户”时的示例。

用户

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;
}
Run Code Online (Sandbox Code Playgroud)

企业

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;
Run Code Online (Sandbox Code Playgroud)

进而

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

但是,您还有两个选择,要么使用Handling Circular References,要么使用Handling Serialization Depth