我遇到的问题给了我这个错误:
序列化对象时检测到循环引用 类“App\Entity\User”(配置限制:1)
我有一个包含任务订单、车辆和用户的企业实体。
与用户、公司和车辆有关系的订单实体。
以及与订单和公司有关系的用户实体。
所以我有这个: 企业.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;
车辆.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;
用户.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);
}
当我想添加新车辆时,出现错误:
序列化对象时检测到循环引用 类“App\Entity\User”(配置限制:1)
我在互联网上看到我必须做一些带有“最大深度”的事情,但我不明白我必须做什么以及具体在哪里
这是我用来添加车辆对象并发送它的功能控制器:
/**
* 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(),
]);
}
对我来说,当我使用API平台时会发生此错误(可能与此案例无关,但可能对其他人有帮助)我必须遵循此评论:
是因为该Entity没有被@ApiResource标记,所以不是 由 API 平台处理(由 Symfony 平台处理),并且如下 是循环引用,会抛出错误。如果该实体 API资源,循环引用会自动处理。 如果你不想让它成为资源,你需要注册一个 自己的循环引用处理程序: https://symfony.com/doc/current/components/serializer.html#handling-circular-references
尝试使用序列化组来避免循环引用(适用于 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;
}
企业
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;
然后
$json = $serializer->serialize(
$user,
'json', ['groups' => ['user','entreprise' /* if you add "user_detail" here you get circular reference */]
);
在我的例子中,我修复了注入序列化器服务,而不是在控制器方法中创建新的序列化器实例。
use Symfony\Component\Serializer\SerializerInterface;
//...
public function createOrder(Request $request, SerializerInterface $serializer)
{
//...
$json = $serializer->serialize($order, 'json', ['groups' => ['normal']]);
//...
}
如果子实体有父实体,并且您不想在序列化中将其作为另一个“子实体”。那么您可以尝试使用“忽略”
use Symfony\Component\Serializer\Annotation\Ignore;
$user->messages(): // 用户有关系为 oneToMany 的消息
然后在 Message 中添加 Ignore to $user:
class Message
// ...
/** @Ignore() */
$user;
CIRCULAR_REFERENCE 错误,这是序列化器调用对象序列化器时防止无限循环的错误。这种情况通常发生在具有多对一和多对多关系的实体上。为了解决这个问题,我们需要通过关注对象 id 来处理序列化器的自定义上下文。
因此在您的控制器中,可以按照下一个示例来完成:
return $this->json($data,Response::HTTP_OK,[],
[ObjectNormalizer::CIRCULAR_REFERENCE_HANDLER=>function ($obj){return $obj->getId();}]);
以及使用序列化器
$encoder = new JsonEncoder();
$defaultContext = [
AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => function ($object, $format, $context) {
return $object->getName();
},];
$normalizer = new ObjectNormalizer(null, null, null, null, null, null, $defaultContext);
$serializer = new Serializer([$normalizer], [$encoder]);
有关更多信息,请查看 symfony 文档 https://symfony.com/doc/current/components/serializer.html#handling-circular-references
对于错误“参考通函”
您必须在要显示的每个属性前面(在您的实体中)标记注释 @Groups("post:read") 然后不要忘记 use 语句“use Symfony\Component\Serializer\Annotation\Groups;” (在您的控制器中)
我利用了 ControllerTrait 的方法“json”:
return $this->json($result, Response::HTTP_OK, [], ['groups' => 'user','entreprise']);
它对我有用。
我发现您可以将循环引用限制传递给serialize()上下文,似乎可以这样做,因为在错误页面中我可以看到[...](配置的限制:10)。例如:
$yourNumber = 2;
$result = $serializer->normalize(
[
'code' => 200,
'message' => 'OK',
'vehicule' => $vehicule,
],
null,
[
AbstractObjectNormalizer::ENABLE_MAX_DEPTH => true,
AbstractNormalizer::CIRCULAR_REFERENCE_LIMIT => $yourNumber
]
);
希望对您有帮助。
当您创建 ManyToOne、OneToMany 或 ManyToMany 类型的关系时,它会出现。要解决这个问题,你可以尝试这个代码;):
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use App\Repository\ClientRepository;
use App\Entity\Client;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
class ClientController extends AbstractController
{
/**
* @Route("/api/client", methods="GET")
*/
public function index(ClientRepository $repository, SerializerInterface $serializer): Response
{
//For avoiding Collection issues of ManyToOne || OneToMany || ManyToMany
//relationship between 2 entities
return $this->json(
json_decode(
$serializer->serialize(
$repository->findAll(),
'json',
[AbstractNormalizer::IGNORED_ATTRIBUTES => ['commandes']]
),
JSON_OBJECT_AS_ARRAY
)
);
}
...
}