【问题标题】:Symfony2 Doctrine2 De-Serialize and Merge Entity issueSymfony2 Doctrine2 反序列化和合并实体问题
【发布时间】:2015-01-26 04:34:34
【问题描述】:

我正在尝试将 json 反序列化为实体,然后合并实体。

我相信我过去曾使用此功能发送 ID 和我希望更新的任何字段。例如:

在我的数据库中:

| id |  first  | last  |   city   |
|  1 |  Jimmy  | James | Seattle  |

然后我将反序列化以下 json 并合并实体

$json = { "id" : 1, "city": "chicago"}
$customer = $serializer->deserialize($json, 'App\CustomerBundle\Entity\Customer', 'json');
$em->merge($customer);

预期的结果是:

| id |  first  | last  |   city   |
|  1 |  Jimmy  | James | Chicago  |

但是我得到以下信息:

| id |  first  | last  |   city   |
|  1 |  null   | null  | Chicago  |

就像我说的那样,我相信我在某些时候可以使用此功能,我不确定这是否与 jms_serializerem->merge 有关。

$customer->getFirst() 在实体合并前后返回 null

【问题讨论】:

  • “合并实体”是什么意思?您想更新数据库中的值或将缺失的属性加载到您的对象中?
  • 我正在尝试通过反序列化包含实体 ID 的 json 来加载实体。我认为它会加载缺少的属性,即:$serializer->deserialize("{"id":1, "city": "chicago"}, .....) 将返回一个具有属性( id => 1, first => Jimmy, last => James, city => chicago) 的实体,其中城市被覆盖,但其余数据已加载。

标签: json symfony doctrine-orm jms-serializer


【解决方案1】:

反序列化器将您的 JSON 字符串转换为一个对象,仅此而已。它将使用您序列化的属性。如果未设置属性,它将保持为空(或您的类中指定的默认值)。

merge 方法也会将空属性持久化到数据库中。

为避免这种情况,请查看来自how to update symfony2/doctrine entity from a @Groups inclusion policy JMSSerializer deserialized entity的答案

持久化实体后,在实体上调用 EntityManager::refresh() 方法应该会加载缺失的属性。

也相关:

【讨论】:

    【解决方案2】:

    您以错误的方式使用 Doctrine 合并。它所做的不是合并的字典定义。来自 Doctrine 文档:

    合并实体是指合并(通常是分离的)实体 进入 EntityManager 的上下文中,以便它们成为受管理的 再次。要将实体的状态合并到 EntityManager 中,请使用 EntityManager#merge($entity) 方法。通过实体的状态 将被合并到该实体的托管副本中,并且该副本将 随后被退回。

    链接:http://doctrine-orm.readthedocs.org/en/latest/reference/working-with-objects.html#merging-entities

    您可能应该一一更新 $customer 的值。

    【讨论】:

    • 有道理,那一定是jms_serializer。我认为如果我要反序列化包含实体 id 的 json,那么它会从数据库中提取任何缺失的字段,即:{ "id":1, "city", "chicago" } 将返回一个带有 (id => 1, firstName => Jimmy, lastName => Jazz, city => Chicago) 但事实并非如此
    • 反序列化器与数据库无关。这是您的实体经理的工作
    【解决方案3】:

    不是很优雅,但我认为这可以完成工作。

    $customer = $em->getRepository('CustomerBundle:Customer')
                ->findOneById($jsonParsedId);
    if ($customer) {
        $customer->setCity($jsonParsedCity);
        $em->persist($customer);
        $em->flush();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-20
      • 1970-01-01
      • 1970-01-01
      • 2013-08-26
      • 2011-04-05
      • 1970-01-01
      • 2016-06-03
      相关资源
      最近更新 更多