我有一个来自Doctrine存储库的实体,我想对它进行序列化,然后返回。实体当然有几个关系,这些关系也有一些关系,等等。但不是全部.
实体的属性已经有一些序列化组。
public function getListAction(SerializerInterface $serializer)
{
// ... Getting data from database with Doctrine
$entities = $this->someRepository->findByConditions(/* ... */);
$serializer->serialize($entities, 'json');
}
在分析器中,我看到它开始填充其余的关系。开始执行数据库查询以填充所有缺失的属性。最后查询超时。
问题:是否有一种方法可以告诉序列化器,只能序列化给定的对象,但不填补缺失的关系?换句话说,禁用延迟加载?
添加一个新的序列化组也不好,因为一些实体有对自身$parent
的引用。所以它最终还是会执行查询。
Serializer无法查看调用是否会触发Doctrine中的延迟加载。您可能可以编写自己的Normalizer,从Doctrine的Proxy-namespace中查找类,但我想,如果它能首先解决您的问题,那么它可能只会变得一团糟。
我能想到的最好的解决方案是在orm级别处理问题,因为这就是导致问题的原因。
例如,您可以使用DQL或QueryBuilder在存储库中创建一个自定义find-方法,它将获取所有必要的数据,包括您想要输出的可能连接的相关对象,并排除您不想要的任何字段。然后我会用不同的水合剂来补水(参见Doctrine Docs:补水)。您可以尝试Doctrine提供的SimpleObjectHydrator。据我所知,这个Hydrator不会使用代理进行延迟加载,而是会尽可能多地加载,它应该仍然会给你原来的实体,但急切加载可能不是你想要的。在这种情况下,你可以把它作为你自己的水合器的参考。编写自定义水合物可能是一个巨大的痛苦,你可以选择数组输出,只是放弃对象水合物完全。在这种情况下,您肯定会丢失实体中的注释,然后您需要在Serializer逻辑中处理这些注释。
你也可以看看本地查询(即SQL),然后自定义结果集映射作为替代方案:参见Doctrine Docs: ResultSetMappingBuilder