问题
I'm using FOSRestBundle in a Symfony project. When it I try to handle a view, it fails during the serialization of my data with the Symfony serializer as well as with the JMSSerializer.
This is the method rendering the response:
DefaultController.php
$em = $this->getDoctrine()->getManager('magellan');
$qb = $em->createQueryBuilder();
$query = $qb->select('h')
->from('DataBundle:Holding', 'h')
->where($qb->expr()->eq('h.id', ':holding_id'))
->setParameter('holding_id', $holding_id)
->getQuery();
$results = $query->getResult();
$view = $this->view($results, 200);
// Everything's ok up to this point
return $this->handleview($view);
And these are my entities:
Holding.php
class Holding
{
...
/**
* @ORM\OneToMany(targetEntity="Subsidiary", mappedBy="holding")
*/
private $subsidiaries;
}
Subsidiary.php
class Subsidiary
{
...
/**
* @ORM\ManyToOne(targetEntity="Holding", inversedBy="subsidiaries")
* @ORM\JoinColumn(name="id_holding", referencedColumnName="id_holding")
*/
private $holding;
/**
* @ORM\OneToMany(targetEntity="Brand", mappedBy="subsidiary")
*/
private $brands;
}
Brand.php
class Brand
{
...
/**
* @ORM\ManyToOne(targetEntity="Subsidiary", inversedBy="brands")
* @ORM\JoinColumn(name="id_subsidiary", referencedColumnName="id_subsidiary")
*/
private $subsidiary;
/**
* @ORM\OneToMany(targetEntity="Product", mappedBy="brand")
*/
private $products;
}
Product.php
class Product
{
...
/**
* @ORM\ManyToOne(targetEntity="Brand", inversedBy="products")
* @ORM\JoinColumn(name="id_brand", referencedColumnName="id_brand")
*/
private $brand;
/**
* @ORM\ManyToOne(targetEntity="Sector", inversedBy="products")
* @ORM\JoinColumn(name="id_sector", referencedColumnName="id_sector")
*/
private $sector;
/**
* @ORM\OneToMany(targetEntity="Commercial", mappedBy="product")
*/
private $commercials;
}
Commercial.php
class Commercial
{
...
/**
* @ORM\ManyToOne(targetEntity="Product", inversedBy="commercials")
* @ORM\JoinColumn(name="id_product", referencedColumnName="id_product")
*/
private $product;
/**
* @ORM\OneToMany(targetEntity="CommercialReport", mappedBy="commercial")
*/
private $reports;
CommercialReport.php
class CommercialReport
{
...
/**
* @ORM\ManyToOne(targetEntity="Commercial", inversedBy="reports")
* @ORM\JoinColumn(name="id_commercial", referencedColumnName="id_commercial")
*/
private $commercial;
}
Sector.php
class Sector
{
...
/**
* @ORM\OneToMany(targetEntity="Product", mappedBy="sector")
*/
private $products;
}
When using the default symfony serializer, I get the following error:
"message":"A circular reference has been detected (configured limit: 1).","class":"Symfony\Component\Serializer\Exception\CircularReferenceException"
And when using the JMSSerializer, when I go to the corresponding page of the controller, the page just never finishes loading. At the same time in the dev.log file new Doctrine.debug entries with requests to my DB are added every second.
回答1:
$normalizers->setCircularReferenceHandler(function ($object) {
return $object->getId();
});
Just add it after you make the instance if your objectNormalizer() it worl perfectly for me
回答2:
If you use FosRestBundle, you can use the GROUPS for the serializer. There is an annotation given by FosRestBundle : @FOS\RestBundle\Controller\Annotations\View(serializerGroups={"user"})
Your group can exclude the circular property.
Another idea you can do this. In your app/config/services.yml
circular_reference_handler:
public: false
class: callback
factory: [AppBundle\Serializer\CircularHandlerFactory, getId]
serializer.normalizer.object:
class: Symfony\Component\Serializer\Normalizer\ObjectNormalizer
arguments: ["@serializer.mapping.class_metadata_factory", null, "@serializer.property_accessor"]
public: false
tags: [serializer.normalizer]
calls:
- method: setCircularReferenceLimit
arguments: [1]
- method: setCircularReferenceHandler
arguments: ["@circular_reference_handler"]
The factory can be like this:
namespace AppBundle\Serializer;
class CircularHandlerFactory
{
/**
* @return \Closure
*/
public static function getId()
{
return function ($object) {
return $object->getId();
};
}
}
来源:https://stackoverflow.com/questions/36775899/symfony-3-0-4-circular-reference-detected-during-serialization-with-fosrestbundl