Symfony 具有关系的实体中的JMSSerializerBundle序列化组

Symfony 具有关系的实体中的JMSSerializerBundle序列化组,symfony,doctrine-orm,jmsserializerbundle,Symfony,Doctrine Orm,Jmsserializerbundle,我在使用组序列化具有许多关系的实体时遇到问题。 我在以这种方式序列化相关实体时遇到问题 假设我有两个实体:产品和相关元素 /** * * @Serializer\ExclusionPolicy("none") */ class Product { /** * Primary key * @var integer $id * * @ORM\Column(name="id", type="integer") * @ORM\Id

我在使用组序列化具有许多关系的实体时遇到问题。 我在以这种方式序列化相关实体时遇到问题

假设我有两个实体:产品和相关元素

/**
 *
 * @Serializer\ExclusionPolicy("none")
 */
class Product {

    /**
     * Primary key
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * 
     * @Serializer\Groups({"list","details"})
     * @Serializer\Type("integer")
     */
    protected $id;

    /**
     * @Serializer\Groups({"list","details"})
     * @Serializer\Type("string")
     */
    protected $name;

    /**
     * @ORM\Column(name="description", type="string", length=4096, nullable=true)
     * 
     * @Serializer\Groups({"details"})
     * @Serializer\Type("string")
     */
    protected $description;

    /**
     * @var ArrayCollection
     * 
     * @ORM\OneToMany(targetEntity="Madden\ProjectBundle\Entity\ProjectResource", mappedBy="project")
     * @Serializer\Groups({"details"})
     * @Serializer\Type("ArrayCollection<Element>")
     */
    protected $details1;

    /**
     * Relation to project tasks
     * @ORM\OneToMany(targetEntity="Madden\ProjectBundle\Entity\ProjectTask", mappedBy="project")
     * @Serializer\Exclude()
     * @Serializer\Type("ArrayCollection<Element>")
     */
    protected $details2;

    ...

}
我的问题是,当我使用“详细信息”组实体序列化产品时,我只想序列化元素的id,但正如您所看到的,实体定义了与产品相同的组(以防我需要元素对象的详细信息),因为我希望在我的所有实体上都有统一的组,并防止生成数百个组,如“产品详细信息”,“元素详细信息”,等等

当我访问relation或类似的东西时,是否有办法最终更改序列化组?也许是汉德勒或者类似的


问候并感谢您的帮助

不幸的是,如果不更改序列化程序库,您真的无法(但请继续阅读;-),至少不能。罪魁祸首是在开始序列化过程的那一刻,组列表就固定在
GroupExclusionStrategy
(由
上下文引用)中。实际上,代码中有一个断言,一旦(反)序列化正在运行,就可以防止修改排除策略

但碰巧的是,我在我的一个项目中也遇到了完全相同的问题,我对序列化程序代码进行了必要的修改。我对代码进行了一些清理,并将其上传到Github()

它添加了新的属性元数据,您可以使用这些元数据在降序到子对象时添加、删除或覆盖组。对于注释,它看起来如下所示:

/**
 * @Serializer\RecursionGroups(set={"foo", "bar"}, add={"baz"}, remove={"Default"})
 */
private $myProperty;
您也应该能够使用XML或Yaml元数据,但是这还没有经过测试,因为我没有使用它们,也没有添加测试用例。请查看参考文档。由于我还没有做过任何优化,如果您的实体非常大并且嵌套很深,那么它可能会对性能产生明显的影响


如果您觉得这有用,或者您有任何建议,请告诉我,因为如果这不仅仅是我需要的,我将添加一些测试并尝试向上游提交。

中实际描述了解决方案


尽管如此,@aferber提出的解决方案在许多方面似乎更好:更易于维护、更不冗长、更灵活……

您需要使用
设置组

不需要官方文档中使用的
\u组
后缀

$context->setGroups([
'默认',//如果需要
//使用此链接实体,但仅显示其id
“链接字段的组”,
“链接字段的组”=>[
'id'//您需要首先定义此组
],
//使用此链接实体并按说明显示字段
“其他链接字段的组”,
“其他链接字段的组”=>[
//举个例子
“默认值”,
"详情",,
],
]);

这不适用于
addGroup
addGroups
!它们都不接受关联数组
setGroups
是您(唯一的?)的解决方案。

我使用了
product\u detail
/
product\u list
etc解决方案,它非常好,因为您始终可以完全控制序列化的内容。缺点显然是序列化多个类时代码会变得多么冗长。。。我也会使用
xxx\u部分
/
xxx\u全部
,而不是
xxx\u列表
/
xxx\u详细信息
@AdrienBrault谢谢回复。是的,我现在正在使用这个解决方案,但它有一个缺点,那就是必须在每个相关实体中定义组,以防我在常用实体中有许多实体字典实体组注释将是巨大的,这就是为什么?正是VirtualProperty解决了我的问题,将关系id-s包含到序列化对象中。但这只是这个问题的部分解决方案,因为可能会有出于性能原因而希望嵌套相关对象的场景。乍一看,它似乎真的很好,我将在今天或明天试用。嗯,对于这个常见问题,使用官方序列化程序不应该是最好的“通用”解决方案,但是还没有找到一个足够好的解决方案,除了使用<代码>虚拟属性解决方案外,你应该考虑拉请求。upstream@aferber这看起来真的很有用。有没有可能提交一份PR来尝试将其输入master?这是序列化程序目前严重缺乏的一项功能,你应该找一个MR.I,作为一个例子,我希望在组件中看到这一点。出于某些愚蠢的原因,官方文档中的解决方案不起作用
/**
 * @Serializer\RecursionGroups(set={"foo", "bar"}, add={"baz"}, remove={"Default"})
 */
private $myProperty;