如何从@Groups 包含策略 JMSSerializer 反序列化实体更新 symfony2/doctrine 实体 [英] how to update symfony2/doctrine entity from a @Groups inclusion policy JMSSerializer deserialized entity

查看:19
本文介绍了如何从@Groups 包含策略 JMSSerializer 反序列化实体更新 symfony2/doctrine 实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用带有 @ExclusionPolicy:None @Groups 包含策略的 JMSSerializer 更新 symfony2/doctrine 实体.

I'm trying to update symfony2/doctrine entities using JMSSerializer with an @ExclusionPolicy:None @Groups Inclusion Policy.

 * @SerializerExclusionPolicy("none")
 */
 class Foo
 {
    /**
     * @SerializerGroups({"flag","edit"})
     */
    protected $id;

    /**
     * @SerializerGroups({"edit"})
     */
    protected $name;

    /**
     * @SerializerGroups({"flag"})
     */
    protected $flag;

    /**
     * @SerializerExclude()
     */
    protected $createdBy;
 }

参考:http://jmsyst.com/libs/serializer/master/reference/annotations

以下记录的结果:

Foo (id:1, name:'bar', flagged:false ,created_by:123)

使用 Group 包含进行序列化以避免序列化我不需要的信息(关联、blob 等),因此当我想更新实体时,我仅反序列化来自 JSON 的实体的更新字段.

is serialized using Group inclusion to avoid serializing information I don't need (associations, blobs, etc..) so when I want to update an entity I deserialize only the updated fields of the entity from the JSON.

$foo->setFlagged(true);
$data = $serializer->serialize($foo, 'json', SerializationContext::create()->setGroups(array("flag")));

result:
{id:1,flagged:true}

当传递回应用程序时反序列化为实体

which when passed back to the application deserializes into the entity

$foo = $serializer->deserialize($jsonFoo,'Foo','json');

result:
Foo (id:1, name:null, flagged:true, created_by:null)

问题是当我尝试将实体合并回条令实体管理器时:

The problem is when I try to merge the entity back into the doctrine entity manager:

$foo = $em->merge($foo);
$em->persist($foo);
$em->flush();

结果 foo 试图用 null 更新排除的属性 (name,created_by).

The resulting foo is trying to update excluded properties (name,created_by) with null.

我如何告诉 JMSSerializer 或 Doctrine Entity Managers 合并我不想用 null 覆盖现有属性?

推荐答案

我找到了答案.

$serializer 是由 symfony2 集成包 JMSSerializerBundle 创建的服务.

$serializer is a service created by the symfony2 integration bundle JMSSerializerBundle.

默认服务是 jms_serializer.serializer 使用默认对象构造函数 UnserializeObjectConstructor 初始化 JMSSerializer 并且对于我需要用 <代码>DoctrineObjectConstructor.

The default service is jms_serializer.serializer initializes the JMSSerializer with the default Object Constructor UnserializeObjectConstructor and for doctrine I needed to deserialize with the DoctrineObjectConstructor.

因为我在项目中只使用 JMSSerializer 来序列化/反序列化原则实体,所以我用正确的对象构造函数服务的别名.

because I only use JMSSerializer in the project for serialize/deserialize of doctrine entities, I overwrote JMSSerializerBundle's jms_serializer.object_constructor with the alias of the proper object constructor service.

<service id="jms_serializer.object_constructor" alias="jms_serializer.doctrine_object_constructor" public="false"/>

是否有更好的方法来配置序列化程序使用的对象构造函数?

我还添加了适当的上下文来反序列化:

I also added the proper context to deserialize:

$serializer->deserialize($jsonFoo,'Foo','json', DeserializationContext::create()->setGroups(array('flag')));

result:
Foo (id:1, name:'bar', flagged:true ,created_by:123)

使用doctrine对象构造函数,它计算出我想要找到该对象并且只对$jsonFoo(和标志组)中提供的字段应用更新.这完全消除了对实体管理器合并的需要,我可以正确地持久化对象.

Using the doctrine object constructor, it figures out that I want to find the object and only apply updates to fields provided in $jsonFoo (and the flag group). This totally eliminates the need for doctrines entity manager merge and I can just persist the object properly.

$em->persist($foo);
$em->flush();

这篇关于如何从@Groups 包含策略 JMSSerializer 反序列化实体更新 symfony2/doctrine 实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆