如何从@Groups包含策略更新symfony2/doctrine实体JMSSerializer反序列化实体

Hey*_*ynn 11 symfony doctrine-orm jmsserializerbundle

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

 * @Serializer\ExclusionPolicy("none")
 */
 class Foo
 {
    /**
     * @Serializer\Groups({"flag","edit"})
     */
    protected $id;

    /**
     * @Serializer\Groups({"edit"})
     */
    protected $name;

    /**
     * @Serializer\Groups({"flag"})
     */
    protected $flag;

    /**
     * @Serializer\Exclude()
     */
    protected $createdBy;
 }
Run Code Online (Sandbox Code Playgroud)

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

以下记录的结果:

Foo (id:1, name:'bar', flagged:false ,created_by:123)
Run Code Online (Sandbox Code Playgroud)

使用Group包含序列化以避免序列化我不需要的信息(关联,blob等等)所以当我想更新实体时,我只从JSON反序列化实体的更新字段.

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

result:
{id:1,flagged:true}
Run Code Online (Sandbox Code Playgroud)

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

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

result:
Foo (id:1, name:null, flagged:true, created_by:null)
Run Code Online (Sandbox Code Playgroud)

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

$foo = $em->merge($foo);
$em->persist($foo);
$em->flush();
Run Code Online (Sandbox Code Playgroud)

生成的foo尝试使用null更新排除的属性(name,created_by).

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

Hey*_*ynn 17

我找到了答案.

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

默认服务使用默认的Object Constructor jms_serializer.serializer初始化,对于我需要使用的反序列化的doctrine .JMSSerializerUnserializeObjectConstructorDoctrineObjectConstructor

因为我只JMSSerializer在项目中使用了doctrine实体的序列化/反序列化,所以用适当的对象构造函数服务的别名覆盖了JMSSerializerBundles jms_serializer.object_constructor.

<service id="jms_serializer.object_constructor" alias="jms_serializer.doctrine_object_constructor" public="false"/>
Run Code Online (Sandbox Code Playgroud)

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

我还添加了反序列化的正确上下文:

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

result:
Foo (id:1, name:'bar', flagged:true ,created_by:123)
Run Code Online (Sandbox Code Playgroud)

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

$em->persist($foo);
$em->flush();
Run Code Online (Sandbox Code Playgroud)