当前位置: 首页 > 知识库问答 >
问题:

在使用FOSRestBundle进行序列化期间检测到Symfony 3.0.4循环引用

唐炜
2023-03-14

我在Symfony项目中使用FOSRestBundle。当我尝试处理视图时,它在使用Symfony序列化器和JMSSerializer序列化我的数据期间失败。

这是呈现响应的方法

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);

这些是我的实体:

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;
}

使用默认symfony序列化程序时,出现以下错误:

"消息":"检测到一个循环引用(配置限制: 1)。","类":"Symfony\Component\Serializer\Excelie\CircularRe的引用异常"

当使用JMSSerializer时,当我转到控制器的相应页面时,页面永远不会完成加载。同时,在dev.log文件中,每秒钟都会添加新的Doctrine.debug条目,其中包含对我的数据库的请求。

共有2个答案

宗政霄
2023-03-14

如果使用FosRestBundle,则可以使用序列化程序的组。FosRestBundle给出了一个注释:@FOS\RestBundle\Controller\Annotations\View(serializerGroups={“user”})

您的组可以排除循环属性。

另一个想法是你可以这样做。在你的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"]

工厂可以是这样的:

namespace AppBundle\Serializer;

class CircularHandlerFactory
{
    /**
     * @return \Closure
     */
    public static function getId()
    {
        return function ($object) {
            return $object->getId();
        };
    }
}
尹辰沛
2023-03-14
    $normalizers->setCircularReferenceHandler(function ($object) {
        return $object->getId();
    });

如果objectNormalizer()非常适合我,请在创建实例后添加它

 类似资料:
  • 我试图用BFS算法在有向图中检测循环。我检测周期的主要想法是:由于BFS只访问每个节点(和边缘)一次,如果我再次遇到已访问的节点;它会导致一个循环。然而,我的代码有时会找到循环,有时不会。 我从维基百科修改的伪代码如下: 我错过了什么?

  • 问题内容: 上课: 和控制器代码: 它适用于LOCALHOST,但不适用于实时服务器: 错误: Json序列化类型的对象时检测到循环引用 我进行了搜索并找到了属性,因此将模型更改为 但是在实时服务器(win2008)上也会发生相同的错误。 如何避免该错误并成功序列化父数据? 问题答案: 尝试以下代码: …或者如果您仅需要父属性: 它并不是解决问题的真正方法,但在序列化DTO时是一种常见的解决方法。

  • 问题内容: 我正在尝试做一个简单的JSON返回,但是我遇到以下问题。 我得到一个HTTP 500,但此问题的标题中显示了例外。我也试过 那也带来了同样的问题。 这是错误还是我的实现? 问题答案: 看来您的对象层次结构中有循环引用,而JSON序列化程序不支持。您是否需要所有列?您只能在视图中选择所需的属性: 这将使您的JSON对象更轻便,更易于理解。如果您有许多属性,则可以使用AutoMapper

  • 问题内容: 我有下表: 存储在其中的实体是按层次结构组织的:如果存在一行,则认为该行是任何内容的“子项” 。由于项目不能从其自身衍生而来,因此我想将存在循环层次序列的行为定为非法: 我该怎么做呢? 另外,我可以在表中添加一个表示层次结构中“级别”的字段: 然后,我要求将其设置为when ,否则。 我正在使用SQL Server 2008 R2。 问题答案: 为了检查循环引用,我使用了触发器和递归C

  • 我有一个简单的类,如下所示: 但我收到以下错误消息: 检测到服务“App\Algorithm\Calculator”的循环引用,路径:“App\Algorithm\Calculator”- MatchService.php 问题是,但我到底做错了什么?

  • 我面临一个问题,导致我出现以下错误: 序列化类“App\Entity\User”(配置的限制:1)的对象时检测到循环引用 我有一个拥有任务订单、车辆和用户的企业实体。 与用户、公司和车辆有关系的订单实体。 以及与订单和公司有关系的用户实体。 所以我有这个:enterprise.php ORD.php: 五ehicule.php: User.php: 当我想添加一辆新车时,我会得到以下错误: 序列化