首页 > 解决方案 > 使用 JMSSerializer 序列化时的空关系

问题描述

我在 Symfony 项目中编写控制器动作时遇到了麻烦,它应该返回数据(在这种特殊情况下是网上商店的订单)。是的……这是一种 REST-API。这条路线只是从一些 JavaScript 中调用的。数据必须在客户端可视化。

问题:

我不知道为什么相关实体的序列化会导致空对象。在这个例子中,它是一个订单的用户,它是空的。

这是一个示例输出:

orders: [
  {
    id: 2,
    created: '2016-05-04T11:40:27+00:00',
    user: {},
  }
]

当我做类似的事情时

$orders = $this->getDoctrine()->getRepository('AppBundle:Order')
  ->findAllCompleted();

$serializationContext->setSerializeNull(true);
$serializationContext->setGroups(['statistics']);

$json = $serializer->serialize($orders, 'json', $serializationContext);
$response = new Response($json, $statusCode, [
  'Content-Type' => 'application/json',
]);

return $response;

...我从服务器得到了一个很好的 JSON 响应,但是每个订单的每个相关实体,比如假设user{}(空的)。

即使我像这样在序列化之前转储相关实体:

[...]
$myOrder = array_filter($orders, function($order) {
  if ($order->getId() == 2) {
    return true;
  }
  return false;
});

dump($myOrder[0]->getUser());
die();

...它会导致一个空的(未水合的)实体。

但是,如果我将此调试代码更改为:

$myOrder = array_filter($orders, function($order) {
  if ($order->getId() == 2) {
    return true;
  }
  return false;
});

dump($myOrder[0]->getUser()->getUsername());
die();

...我得到一个带有该实体用户名值的清晰输出(字符串)。

所以我认为问题在于非水合实体,而不是序列化程序或其错误配置。

我怎样才能让 JMSSerializer 来处理这些相关实体的水合作用?

我在文档中没有找到任何提示...

顺便说一句,这是订单和用户的 JMS 实体配置。

AppBundle\Entity\User:
  exclusion_policy: ALL
  properties:
    userMeta:
      expose: true
    address:
      expose: true
    username:
      expose: true
    email:
      expose: true
    isReseller:
      expose: true
    acceptPublicOrders:
      expose: true
    vatNumber:
      expose: true
    taxRate:
      expose: true


AppBundle\Entity\Order:
  exclusion_policy: NONE
  properties:
    id:
      groups: ['statistics']

    user:
      groups: ['statistics']

    configuration:
      groups: ['statistics']

    created:
      groups: ['statistics']

    invoiceItems:
      groups: ['statistics']
      exclude: true

标签: symfonydoctrine-ormjmsserializerbundlejms-serializer

解决方案


我认为您的问题是由学说延迟加载引起的,也许您可​​以尝试在您的 Order 实体中将用户关联的获取模式更改为 EAGER

@ManyToOne(targetEntity="Cart", cascade={"all"}, fetch="EAGER")

默认情况下,我认为它不会获取关联,除非您像在此处那样直接调用它

转储($myOrder[0]->getUser()->getUsername());

https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#annref-onetoone

或者,如果您使用 DQL
14.7.6.6。临时更改 DQL 中的 fetch 模式

http://doctrine-orm.readthedocs.io/en/latest/reference/dql-doctrine-query-language.html#temporarily-change-fetch-mode-in-dql

编辑:我错了我做了一些测试,在延迟加载或急切的情况下一切正常,直到我尝试使用组,即使字段暴露你不使用默认组,所以它只使用“统计”组的东西它尝试在此处添加默认组

$serializationContext->setGroups(['Default','statistics']);

或者在您的用户字段上添加对我有用的统计组


推荐阅读