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



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

这是呈现响应的方法:

默认控制器.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);

这些是我的实体:

持有.php

class Holding
{
    ...
    /**
     * @ORMOneToMany(targetEntity="Subsidiary", mappedBy="holding")
     */
    private $subsidiaries;
}

子公司.php

class Subsidiary
{
    ...
    /**
     * @ORMManyToOne(targetEntity="Holding", inversedBy="subsidiaries")
     * @ORMJoinColumn(name="id_holding", referencedColumnName="id_holding")
     */
    private $holding;
    /**
     * @ORMOneToMany(targetEntity="Brand", mappedBy="subsidiary")
     */
    private $brands;
}

品牌.php

class Brand
{
    ...
    /**
     * @ORMManyToOne(targetEntity="Subsidiary", inversedBy="brands")
     * @ORMJoinColumn(name="id_subsidiary", referencedColumnName="id_subsidiary")
     */
    private $subsidiary;
    /**
     * @ORMOneToMany(targetEntity="Product", mappedBy="brand")
     */
    private $products;
}

产品.php

class Product
{
    ...
    /**
     * @ORMManyToOne(targetEntity="Brand", inversedBy="products")
     * @ORMJoinColumn(name="id_brand", referencedColumnName="id_brand")
     */
    private $brand;
    /**
     * @ORMManyToOne(targetEntity="Sector", inversedBy="products")
     * @ORMJoinColumn(name="id_sector", referencedColumnName="id_sector")
     */
    private $sector;
    /**
     * @ORMOneToMany(targetEntity="Commercial", mappedBy="product")
     */
    private $commercials;
}

商业.php

class Commercial
{
    ...
    /**
     * @ORMManyToOne(targetEntity="Product", inversedBy="commercials")
     * @ORMJoinColumn(name="id_product", referencedColumnName="id_product")
     */
    private $product;
    /**
     * @ORMOneToMany(targetEntity="CommercialReport", mappedBy="commercial")
     */
    private $reports;

商业报告.php

class CommercialReport
{
    ...
    /**
     * @ORMManyToOne(targetEntity="Commercial", inversedBy="reports")
     * @ORMJoinColumn(name="id_commercial", referencedColumnName="id_commercial")
     */
    private $commercial;
}

部门.php

class Sector
{
    ...
    /**
     * @ORMOneToMany(targetEntity="Product", mappedBy="sector")
     */
    private $products;
}

使用默认的symfony序列化程序时,我收到以下错误:

"消息":"检测到循环引用(配置的限制: 1).","class":"Symfony\Component\Serializer\Exception\CircularReferenceException"

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

    $normalizers->setCircularReferenceHandler(function ($object) {
        return $object->getId();
    });

只需在创建实例后添加它,如果您的 objectNormalizer()它对我来说是完美的

如果使用 FosRestBundle,则可以将 GROUPS 用于序列化程序。有一个由 FosRestBundle 给出的注释:@FOS\RestBundle\Controller\Annotations\View(serializerGroups={"user"})

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

另一个想法你可以做到这一点。在你的app/config/services.yml中

circular_reference_handler:
    public: false
    class: callback
    factory: [AppBundleSerializerCircularHandlerFactory, getId]
serializer.normalizer.object:
    class: SymfonyComponentSerializerNormalizerObjectNormalizer
    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 AppBundleSerializer;
class CircularHandlerFactory
{
    /**
     * @return Closure
     */
    public static function getId()
    {
        return function ($object) {
            return $object->getId();
        };
    }
}

相关内容

  • 没有找到相关文章

最新更新